【发布时间】:2014-07-27 17:58:03
【问题描述】:
我在 DataGrid 中有 2 个 ComboBoxes。当在第一个ComboBox 中进行选择时,我想更新第二个ComboBox 的ItemsSource。我刚开始学习Silverlight,我正在尝试遵循MVVM 模式。这就是我到目前为止所得到的。
型号
public class Country : ViewModelBase
{
private string name;
public string Name {...}
public string Code { get; set; }
}
public class City : ViewModelBase
{
private string name;
public string Name {...}
public string Code { get; set; }
}
public class Location : ViewModelBase
{
private City city;
public City City {...}
private Country country;
public Country Country {...}
}
视图模型
public class CountryCityViewModel : ViewModelBase
{
private Location selectedLocation;
public Location SelectedLocation {...}
IRepo Repo { get; set; }
public ObservableCollection<Location> Locations { get; set; }
public ObservableCollection<Country> Countries { get; set; }
public ObservableCollection<City> Cities { get; set; }
public CountryCityViewModel(IRepo repo)
{
this.Repo = repo;
Countries = new ObservableCollection<Country>(repo.LoadCountries());
Cities = new ObservableCollection<City>();
Locations = new ObservableCollection<Location>(repo.LoadLocations());
this.PropertyChanged += CountryCityViewModel_PropertyChanged;
}
private void UpdateCityComboBoxItemsSource(object obj)
{
Country selCountry = ( (Country) obj );
if (obj != null)
{
UpdateCities(selCountry);
}
}
void CountryCityViewModel_PropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "SelectedLocation")
{
UpdateCities(SelectedLocation.Country);
}
}
private void UpdateCities(Country country)
{
var newCities = Repo.LoadCities(country);
Cities.Clear();
foreach (var city in newCities)
{
Cities.Add(city);
}
OnPropertyChanged("Cities");
}
}
XAML
<Custom:CustomDataGrid x:Name="CountryCity" AutoGenerateColumns="False"
ColumnWidth="*" RowHeight="25"
ItemsSource="{Binding Path=Locations}"
SelectedItem="{Binding Path=SelectedLocation,
Mode=TwoWay}">
<Custom:CustomDataGrid.Columns>
<sdk:DataGridTemplateColumn Header="Country">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Country.Name}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="CountryComboBox"
ItemsSource="{Binding
RelativeSource={RelativeSource
AncestorType=Custom:CustomDataGrid},
Path=DataContext.Countries}"
SelectedItem="{Binding Path=Country,
Mode=TwoWay}"
DisplayMemberPath="Name">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding
RelativeSource={RelativeSource
AncestorType=Custom:CustomDataGrid},
Path=
DataContext.
CountryComboBoxItemSelectedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn Header="City">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=City.Name}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="CityyComboBox"
ItemsSource="{Binding
RelativeSource={RelativeSource
AncestorType=Custom:CustomDataGrid},
Path=DataContext.Cities}"
SelectedItem="{Binding Path=City, Mode=TwoWay}"
DisplayMemberPath="Name"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
</Custom:CustomDataGrid.Columns>
</Custom:CustomDataGrid>
首先我试图捕捉SelectedLocation 的PropertyChanged 事件。但这仅有助于在我选择数据网格的下一行时更新Cities。这不是所需的功能。我想在CountryComboBox 中做出选择后立即更新Cities。
我尝试使用EventTriggers 进行试验,但我不确定我应该听哪个事件和哪个控件才能获得Selecteditem 的CountryComboBox。
非常感谢任何建议或链接。
谢谢
编辑
在CountryComboBox 中使用EventTrigger 的CommandParameter 属性似乎对我有用。
public ICommand CountryComboBoxItemSelectedCommand { get; set; }
CountryComboBoxItemSelectedCommand = new
RelayCommand(UpdateCityComboBoxItemsSource);
和xaml
<ComboBox x:Name="CountryComboBox"
ItemsSource="{Binding Path=DataContext.Countries,
RelativeSource={RelativeSource AncestorType=Custom:CustomDataGrid}}"
SelectedItem="{Binding Path=Country, Mode=TwoWay}"
DisplayMemberPath="Name">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding
Path=DataContext.CountryComboBoxItemSelectedCommand,
RelativeSource={RelativeSource AncestorType=Custom:CustomDataGrid}}"
CommandParameter="{Binding SelectedItem,ElementName=CountryComboBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
【问题讨论】:
-
ItemsSource 应该如何改变?改成什么?我在您的代码中只能看到一个城市代码列表,那么您要完成什么?再次将该列表交换为完全相同的列表?还是要更改 Address 对象中的城市代码以匹配城市名称?
-
@Martin 我的问题可能没有最好的例子。我用一个更好的问题更新了问题。我一直在寻找的是,当用户从
CountryComboBox中选择Country时,我想使用与所选Country相关的City对象集合来更新CityComboBox的可用选项。跨度>
标签: silverlight dynamic datagrid combobox selecteditem