WPF - Binding to CheckBox not working in a HierarchicalDataTemplate - binding

In a WPF treeview I am trying to automatically check the children if the parent node is being checked. I am using a view model for that and a bindable object for the nodes, however all my attempts failed. Here is the code (C# + XAML). Any ideas would be greatly appreciated
<Window x:Class="TestCheckBoxBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestCheckBoxBinding"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True"/>
</Style>
<HierarchicalDataTemplate DataType="{x:Type local:TestCategory}" ItemsSource="{Binding Tests, Mode=OneTime}">
<Label Content="{Binding Name}"></Label>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Test}" ItemsSource="{Binding Children, Mode=OneTime}">
<StackPanel Orientation="Horizontal">
<CheckBox VerticalAlignment="Center" IsChecked="{Binding IsChecked, Mode=TwoWay}"></CheckBox>
<Label Content="{Binding Name}"></Label>
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView ItemsSource="{Binding Categories, Mode=OneTime}"></TreeView>
</Grid>
public class TestsViewModel
{
public static void PopulateList(TestsViewModel vm)
{
TestCategory cat1 = new TestCategory() { Id = 1, Name = "First category" };
Test t1 = new Test() { Name = "Test1" };
Test t2 = new Test() { Name = "Test2" };
Test t3 = new Test() { Name = "Test3" };
t1.AddChild(t2);
t1.AddChild(t3);
Test t4 = new Test() { Name = "Test4" };
cat1.AddTest(t1);
cat1.AddTest(t4);
vm.AddTestCategory(cat1);
TestCategory cat2 = new TestCategory() { Id = 2, Name = "Second category" };
Test t5 = new Test() { Name = "Test1" };
Test t6 = new Test() { Name = "Test2" };
Test t7 = new Test() { Name = "Test3" };
t6.AddChild(t7);
Test t8 = new Test() { Name = "Test4" };
cat2.AddTest(t5);
cat2.AddTest(t6);
cat2.AddTest(t8);
vm.AddTestCategory(cat2);
}
private readonly IEnumerable<TestCategory> categories = new List<TestCategory>();
public IEnumerable<TestCategory> Categories { get { return categories; } }
public void AddTestCategory(TestCategory testCategory)
{
((IList<TestCategory>)categories).Add(testCategory);
}
}
public class TestCategory
{
public int Id { get; set; }
public string Name { get; set; }
private readonly IEnumerable<Test> tests = new List<Test>();
public IEnumerable<Test> Tests { get { return tests; } }
public void AddTest(Test t)
{
((IList<Test>)tests).Add(t);
}
}
public class Test : INotifyPropertyChanged
{
private string name;
public string Name
{
set
{
if (name != value)
{
name = value;
this.OnPropertyChanged("Name");
}
}
get { return name; }
}
public bool? isChecked = false;
public bool? IsChecked
{
get { return isChecked; }
set
{
if (isChecked != value)
{
isChecked = value;
if (children.Count() > 0)
{
foreach (var test in children)
{
test.isChecked = value;
test.Name += ".";
}
}
this.OnPropertyChanged("IsChecked");
}
}
}
public void AddChild(Test test)
{
((IList<Test>)children).Add(test);
}
private readonly IEnumerable<Test> children = new List<Test>();
public IEnumerable<Test> Children
{
get { return children; }
}
#region INotifyPropertyChanged Members
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string propName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}

Oups, child checkboxes are not being checked because I wasn't setting their IsChecked property. I was setting the isChecked field, which bypasses the property setter and prevents PropertyChanged from being raised.

Related

How to retrive data from dynamic text box using Blazor

MyCustomControl.razor
<input type="text" id="#id" />
#code {
[Parameter]
public string id { get; set; }
}
Test.Razor
#page "/test"
<button #onclick="#addCompoment">add text box</button>
<div class="simple-list-list">
#if (componentListTest == null)
{
<p>You have no items in your list</p>
}
else
{
<ul>
#foreach (var item in componentListTest)
{
#item<br/>
}
</ul>
}
</div>
#functions {
private List<RenderFragment> componentListTest { get; set; }
private int currentCount { get; set; }
private string TxtExample { get; set; }
protected void OnInit()
{
currentCount = 0;
componentListTest = new List<RenderFragment>();
}
protected void addCompoment()
{
if(componentListTest==null)
{
componentListTest = new List<RenderFragment>();
}
componentListTest.Add(CreateDynamicComponent(currentCount));
currentCount++;
}
RenderFragment CreateDynamicComponent(int counter) => builder =>
{
try
{
var seq = 0;
builder.OpenComponent(seq, typeof(MyCustomControl));
builder.AddAttribute(++seq, "id", "listed-" + counter);
builder.CloseComponent();
}
catch (Exception ex)
{
throw;
}
};
}
After Adding the textbox dynamically,how to retrieve all input data from the textbox (after clicking on the submit button.)
How to interact with dynamic component and fetch Value.
MyCustomControl is component, Append in Test Razor Page.
for these component create an attribute like bind-value to get input field data given by user
There are a couple of solutions to this type of issue, depending on the general design of your app, constraints, and such like. The following solution is simple. Generally speaking, it involves passing the value of the added text box to a parent component to be saved in a list object. The parent component has a button that displays the list of text when clicked.
The following is the definition of the child component:
MyCustomControl.razor
<input type="text" #bind="#Value" id="#ID" />
#code {
private string _value;
public string Value
{
get { return _value; }
set
{
if (_value != value)
{
_value = value;
if (SetValue.HasDelegate)
{
SetValue.InvokeAsync(value);
}
}
}
}
[Parameter]
public string ID { get; set; }
[Parameter]
public EventCallback<string> SetValue { get; set; }
}
Usage in a parent component
<button #onclick="#addCompoment">add text box</button>
<div class="simple-list-list">
#if (componentListTest == null)
{
<p>You have no items in your list</p>
}
else
{
<ul>
#foreach (var item in componentListTest)
{
#item
<br />
}
</ul>
}
</div>
<p><button #onclick="#ShowValues">Show values</button></p>
#if (Display)
{
<ul>
#foreach (var value in values)
{
<li>#value</li>
}
</ul>
}
#code {
public void SetValue(string value)
{
values.Add(value);
}
private List<RenderFragment> componentListTest { get; set; }
private List<string> values = new List<string>();
private int currentCount { get; set; }
protected override void OnInitialized()
{
currentCount = 0;
componentListTest = new List<RenderFragment>();
}
private bool Display;
private void ShowValues()
{
if (values.Any())
{
Display = true;
}
}
protected void addCompoment()
{
if (componentListTest == null)
{
componentListTest = new List<RenderFragment>();
}
componentListTest.Add(CreateDynamicComponent(currentCount));
currentCount++;
}
RenderFragment CreateDynamicComponent(int counter) => builder =>
{
try
{
builder.OpenComponent(0, typeof(MyCustomControl));
builder.AddAttribute(1, "id", "listed-" + counter);
builder.AddAttribute(2, "SetValue", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<Microsoft.AspNetCore.Components.EventCallback<System.String>>(Microsoft.AspNetCore.Components.EventCallback.Factory.Create<System.String>(this, this.SetValue )));
builder.CloseComponent();
}
catch (Exception ex)
{
throw;
}
};
}
Note:
Notice the SetValue attribute I've added to the CreateDynamicComponent's builder. This provides a Component Parameter to MyCustomControl of type EventCallback<string> which is assigned to the SetValue parameter property:
[Parameter]
public EventCallback<string> SetValue { get; set; }
And it is used (trigger the method which is also called SetValue in the parent component. You can change the name if you like) to pass the changed value from the child component to the parent component.
Use code instead of functions.
Note that I've made some modifications in your code: OnInitialized instead of OnInit (obsolete), sequence numbers should not created the way you do. Refer to this article written by Steve Sanderson ...
Hope this helps...

struts2 jquery grid data not loaded when implements model driven

My web application not loading data when I implements model driven in action class. It works fine when remove modeldriven.
action class :
package action;
import action.UserBean;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import service.OrganisationBo;
import model.AtDivision;
import model.AtOrganisation;
public class OraganisationAction extends ActionSupport implements ModelDriven<UserBean> {
private String uname;
private String passwd;
private String sidx;
// Search Field
private String searchField;
// The Search String
private String searchString;
// he Search Operation ['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
private String searchOper;
// Your Total Pages
private Integer total = 0;
//Your result List
private List<UserBean> gridModel;
//get how many rows we want to have into the grid - rowNum attribute in the grid
private Integer rows = 0;
//Get the requested page. By default grid sets this to 1.
private Integer page = 0;
// sorting order - asc or desc
private String sord;
private boolean loadonce = false;
// All Record
private Integer records = 0;
private String includepage;
private List<UserBean> myList;
private String oper;
private String id;
private String contact;
private String country;
UserBean ubs = new UserBean();
private AtOrganisation org = new AtOrganisation();
private AtDivision div = new AtDivision();
private List<AtOrganisation> orglist = new ArrayList<AtOrganisation>();
OrganisationBo orgBo;
private String aoId;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getSidx() {
return sidx;
}
public void setSidx(String sidx) {
this.sidx = sidx;
}
public String getSearchField() {
return searchField;
}
public void setSearchField(String searchField) {
this.searchField = searchField;
}
public String getSearchString() {
return searchString;
}
public void setSearchString(String searchString) {
this.searchString = searchString;
}
public String getSearchOper() {
return searchOper;
}
public void setSearchOper(String searchOper) {
this.searchOper = searchOper;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public List<UserBean> getGridModel() {
return gridModel;
}
public void setGridModel(List<UserBean> gridModel) {
this.gridModel = gridModel;
}
public Integer getRows() {
return rows;
}
public void setRows(Integer rows) {
this.rows = rows;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public String getSord() {
return sord;
}
public void setSord(String sord) {
this.sord = sord;
}
public boolean isLoadonce() {
return loadonce;
}
public void setLoadonce(boolean loadonce) {
this.loadonce = loadonce;
}
public Integer getRecords() {
return records;
}
public void setRecords(Integer records) {
this.records = records;
}
public String getIncludepage() {
return includepage;
}
public void setIncludepage(String includepage) {
this.includepage = includepage;
}
public List<UserBean> getMyList() {
return myList;
}
public void setMyList(List<UserBean> myList) {
this.myList = myList;
}
public String getOper() {
return oper;
}
public void setOper(String oper) {
this.oper = oper;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public List<AtOrganisation> getOrglist() {
return orglist;
}
public void setOrglist(List<AtOrganisation> orglist) {
this.orglist = orglist;
}
public String getAoId() {
return aoId;
}
public void setAoId(String aoId) {
this.aoId = aoId;
}
public void setOrgBo(OrganisationBo orgBo) {
this.orgBo = orgBo;
}
public AtDivision getDiv() {
return div;
}
public void setDiv(AtDivision div) {
this.div = div;
}
public AtOrganisation getOrg() {
return org;
}
public void setOrg(AtOrganisation org) {
this.org = org;
}
public String execute() throws Exception {
myList = DAO.buildList();
setRecords(DAO.count());
int to = (getRows() * getPage());
int from = to - getRows();
if (to > getRecords()) {
to = getRecords();
}
if (loadonce) {
setGridModel(myList);
} else {
if (searchString != null && searchOper != null && !searchString.equals("") && !searchOper.equals("")) {
System.out.println("Searching within Database");
if (searchOper.equalsIgnoreCase("cn")) {
// setGridModel(DAO.findbyName(searchString));
}
} else {
System.out.println("Not Searching Anywhere");
//setGridModel(DAO.find(from, to));
System.out.println("dili 4444");
setGridModel(myList);
}
}
total = (int) Math.ceil((double) getRecords() / (double) getRows());
System.out.println("tot " + total);
System.out.println(gridModel.size());
return SUCCESS;
}
#Override
public UserBean getModel() {
return ubs;
}
}
Struts.xml :
<package name="default" extends="struts-default,json-default">
<action name="gridaction" class="action.OraganisationAction" >
<result name="success" type="json"/>
</action>
</package>
</struts>
index.jsp :
<%--
Document : index
Created on : 15 Nov, 2011, 11:45:45 PM
Author : XCoder
--%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib prefix="s" uri="/struts-tags" %>
<%#taglib prefix="sj" uri="/struts-jquery-tags" %>
<%#taglib prefix="sjg" uri="/struts-jquery-grid-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<sj:head jquerytheme="start" jqueryui="true"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<s:url id="remoteurl" action="gridaction"/>
<sjg:grid
id="sjgrid"
caption="Grid Model"
dataType="json"
href="%{remoteurl}"
pager="true"
rowList="10,20,100"
rowNum="5"
navigator="true"
width="999"
navigatorSearchOptions="{sopt:['eq','ne','lt','gt']}"
navigatorAddOptions="{height:280,reloadAfterSubmit:true}"
navigatorEditOptions="{height:280,reloadAfterSubmit:false}"
navigatorEdit="false"
navigatorView="false"
navigatorDelete="true"
navigatorDeleteOptions="{height:280,reloadAfterSubmit:true}"
gridModel="gridModel"
editurl="%{editurl}"
editinline="true"
onSelectRowTopics="rowselect"
>
<sjg:gridColumn name="iduser" formatter="integer" title="iduser" key="true" hidden="true"/>
<sjg:gridColumn name="uname" title="Username" editable="true" align="center"
editrules="{required:true}"
/>
<sjg:gridColumn name="passwd" title="Password" editable="true" align="center"
editrules="{required:true}"
/>
<sjg:gridColumn name="country" title="Country" editable="true" align="center"
edittype="select"
editoptions="{dataUrl:'%{selecturl}'}"
/>
<sjg:gridColumn name="contact" title="Contact No" editable="true" align="center"
editrules="{required:true,number:true,integer:true}"
/>
</sjg:grid>
</body>
</html>
cant we implement model driven with jqgrid or my code is wrong?
EDIT:
Just figure out that modeldriven work fine with old lib set
struts2-convention-plugin-2.1.8,
struts2-core-2.1.8.1,
struts2-jquery-grid-plugin-2.5.0,
struts2-jquery-plugin-2.5.0,
struts2-json-plugin-2.1.8,
xwork-core-2.1.6.
But when I update project into new version of struts grid is not fill with data. New lib set is as follows :
struts2-convention-plugin-2.3.16,
struts2-core-2.3.16,
struts2-jquery-grid-plugin-3.7.1,
struts2-jquery-plugin-3.7.0 ,
struts2-json-plugin-2.3.16.3
xwork-core-2.3.16.
Anyone knows what happening here?

How can I add TwoWay Binding to my CustomControl in WindowsPhone?

I want to use twoway binding in my customcontrol. It's codes;
CustomControl;
<Grid>
<PasswordBox x:Name="passwordB" GotFocus="PasswordBox_GotFocus" LostFocus="PasswordBox_LostFocus" PasswordChanged="passwordB_PasswordChanged" Style="{StaticResource AkbankControlStyleWatermarkPasswordBoxLoginFormInputPasswordBox}"></PasswordBox>
<TextBlock x:Name="lblWaterMark" MouseLeftButtonDown="lblWaterMark_Tapped" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="20,10,20,10" Opacity="0.8" FontFamily="Segoe UI" FontSize="16" Foreground="#FF8E8E8E" FontWeight="SemiBold"></TextBlock>
</Grid>
It's name is WatermarkPasswordTextBox :)
DependencyProperty;
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.Register(
"PassText",
typeof(string),
typeof(WatermarkPasswordTextBox),
new PropertyMetadata(""));
Properties;
private string _passText = "";
public string PassText
{
get
{
if (passwordB != null)
{
_passText = passwordB.Password;
return _passText;
}
else
{
return String.Empty;
}
}
set
{
if (passwordB != null)
{
SetProperty<string>(ref _passText, value, "PassText");
passwordB.Password = _passText;
passwordB_PasswordChanged(passwordB, null);
}
else
{
SetProperty<string>(ref _passText, value, "PassText");
}
}
}
OnApplyTemplate ;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.SetBinding(
WatermarkPasswordTextBox.PasswordProperty,
new Binding
{
Path = new PropertyPath("PassText"),
Mode = BindingMode.TwoWay,
Source = this
});
}
My Xaml;
<CustomControls:WatermarkPasswordTextBox
PassText="{Binding Password,Mode=TwoWay}"
Padding="5"
x:Name="CustomerPasswordTextBox"
x:FieldModifier="public"
LenghtMax="6"
Watermark="{Binding LocalizedResources.PasswordWatermarkWatermark,Source={StaticResource LocalizedStrings}}"
RelayedKeyUp="CustomerPasswordTextBox_KeyUp"
HorizontalContentAlignment="Left"/>
Error Code;
System.ArgumentException: Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'.
This code is giving runtime error.
Thanks.

Binding data from ObservableCollection<User> to xaml page

i am trying to bind the data from ObservableCollection to xaml page
pls let me know hoe to achive this
Xaml page
<UserControl.Resources>
<DataTemplate x:Key="User" >
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource User}}">
<data:DataGrid AutoGenerateColumns="True"
HeadersVisibility="All"
ItemsSource="{Binding }"
RowBackground="Cornsilk"
AlternatingRowBackground="BlanchedAlmond"
ColumnWidth="85" RowHeight="30"
IsReadOnly="True" CanUserResizeColumns="False">
</data:DataGrid>
</Grid>
.cs page
ObservableCollection<User> users;
public SLObservableCollectionSample()
{
InitializeComponent();
users = getUserCollection();
}
ObservableCollection<User> getUserCollection()
{
ObservableCollection<User> rVal = new ObservableCollection<User>();
rVal.Add(new User { Name = "Tom", Score = 2 });
rVal.Add(new User { Name = "Sam", Score = 3 });
rVal.Add(new User { Name = "John", Score = 4 });
rVal.Add(new User { Name = "Dave", Score = 5 });
rVal.Add(new User { Name = "Sue", Score = 1 });
return rVal;
}
#region User INotifyPropertyChanged
public class User : INotifyPropertyChanged
{
private string name;
public string Name
{
get { return name; }
set
{
if (value != name)
{
name = value;
onPropertyChanged(this, "Name");
}
}
}
private long score;
public long Score
{
get { return score; }
set
{
if (score != value)
{
score = value;
onPropertyChanged(this, "Score");
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void onPropertyChanged(object sender, string propertyName)
{
if (this.PropertyChanged != null)
{
PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#endregion
Thanks
Prince

DataBinding 2 ComboBoxes wpf

I need to build a form where I have 2 comboBoxes .
Select country and you get the cities of that country.
I m new to wpf so help me as I not sure what I am missing.
At the moment It doesnt even populate it.
Any help suggestions really appreaciated!
This is what I have done:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var window = new MainWindow();
var countryCitymodel = new CountryCityModel();
var repository = new CountryCityRepository();
var viewModel = new CountryCityViewModel(countryCitymodel, repository);
window.Show();
}
}
MainWindow xaml
<Window x:Class="WpfDatabinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:WpfDatabinding.Views"
Title="MainWindow" Height="350" Width="525">
<Grid>
<view:CountryCityView />
</Grid>
</Window>
CountryCityView xaml
<UserControl x:Class="WpfDatabinding.Views.CountryCityView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="75" d:DesignWidth="300">
<Grid Height="64" Width="291">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="97"/>
<ColumnDefinition Width="13" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="Countries" Margin="-6,6,5,0" Grid.ColumnSpan="2" Height="33"></Label>
<Label Grid.Row="1" Content="Cities" Grid.ColumnSpan="2"></Label>
<ComboBox Name="cboCountries"
ItemsSource="{Binding Path=Countries}"
SelectedValuePath="Name"
DisplayMemberPath="{Binding Name}"
Grid.Column="2"
Margin="0,10"></ComboBox>
<ComboBox Name="cboCities"
Grid.Column="2"
Grid.Row="1"
ItemsSource="{Binding Path=Cities}" Height="20" Margin="0,0,0,1">
</ComboBox>
</Grid>
</UserControl>
CountryCityView
public partial class CountyrCityView:UserControl
{
public CountryCityView()
{
InitializeComponents();
}
public CountryCityView(CountryCityViewModel countryCityViewModel)
{
InitializeComponents();
DataContext=countryCityViewModel;
}
}
CountryCityViewModel
public class CountryCityViewModel : ViewModelBase
{
private readonly CountryCityModel _countryCityModel;
readonly CountryCityRepository _repository;
RelayCommand _getCountriesCommand;
private RelayCommand _getCitiesCommand;
public CountryCityViewModel(CountryCityModel countryCityModel, CountryCityRepository repository)
{
_countryCityModel = countryCityModel;
_repository = repository;
GetCountries.Execute(null);
}
public List<Country> Countries
{
get { return _countryCityModel.Countries; }
set
{
_countryCityModel.Countries = value;
OnPropertyChanged("Countries");
}
}
public List<City> Cities
{
get { return _countryCityModel.Cities; }
set
{
_countryCityModel.Cities = value;
OnPropertyChanged("Cities");
}
}
public Country SelectedCountry
{
get { return _countryCityModel.SelectedCountry; }
set
{
_countryCityModel.SelectedCountry = value;
OnPropertyChanged("SelectedCountry");
}
}
public City SelectedCity
{
get { return _countryCityModel.SelectedCity; }
set
{
_countryCityModel.SelectedCity = value;
OnPropertyChanged("SelectedCity");
}
}
public ICommand GetCountries
{
get
{
if (_getCountriesCommand == null)
{
_getCountriesCommand = new RelayCommand(param => GetCountryList(), param => CanGetCountries());
}
return _getCountriesCommand;
}
}
public ICommand GetCities
{
get
{
if (_getCitiesCommand == null)
{
_getCitiesCommand = new RelayCommand(param => GetCityList(), param => CanGetCities());
}
return _getCitiesCommand;
}
}
private List<Country> GetCountryList()
{
Countries = _repository.GetCountries();
return Countries;
}
private static bool CanGetCountries()
{
return true;
}
private List<City> GetCityList()
{
Cities = _repository.GetCities(SelectedCountry.Name);
return Cities;
}
private static bool CanGetCities()
{
return true;
}
}
Model
public class CountryCityModel
{
public List<Country> Countries { get; set; }
public List<City> Cities { get; set; }
public Country SelectedCountry{ get; set; }
public City SelectedCity { get; set; }
}
Types
public class City
{
public string Name { get; set; }
public string CountryName { get; set; }
}
public class Country
{
public string Name { get; set; }
}
Repository
public List<Country>GetCountries()
{
return new List<Country>
{
new Country{Name = "Italy"},
new Country{Name = "Germany"},
new Country{Name = "France"},
new Country{Name = "England"}
};
}
public List<City> GetCities(string countryName)
{
return Cities().Where(c => c.CountryName == countryName).ToList();
}
private static IEnumerable<City> Cities()
{
return new List<City>
{
new City { CountryName="Italy",Name = "Rome"},
new City {CountryName="France",Name = "Paris"},
new City{CountryName="Germany",Name ="Berlin"},
new City{CountryName="England",Name ="London"}
};
}
}
Are you setting the data context of the view to your ViewModel somewhere? I don't see that in the code listed above.
e.g.
var viewModel = new CountryCityViewModel(countryCitymodel, repository);
window.DataContext = viewModel;

Resources