【问题标题】:Update ComboBox ItemsSource based on SelectedItem of another ComboBox inside a Silverlight DataGrid根据 Silverlight DataGrid 中另一个 ComboBox 的 SelectedItem 更新 ComboBox ItemsSource
【发布时间】:2014-07-27 17:58:03
【问题描述】:

我在 DataGrid 中有 2 个 ComboBoxes。当在第一个ComboBox 中进行选择时,我想更新第二个ComboBoxItemsSource。我刚开始学习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>

首先我试图捕捉SelectedLocationPropertyChanged 事件。但这仅有助于在我选择数据网格的下一行时更新Cities。这不是所需的功能。我想在CountryComboBox 中做出选择后立即更新Cities

我尝试使用EventTriggers 进行试验,但我不确定我应该听哪个事件和哪个控件才能获得SelecteditemCountryComboBox

非常感谢任何建议或链接。

谢谢

编辑

CountryComboBox 中使用EventTriggerCommandParameter 属性似乎对我有用。

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


【解决方案1】:

我已经这样做了很多次了。

我以前做的是在 XAML 中为 Country 组合框创建 SelectedItem 属性。

假设,SelectedItem 属性的名称是“SelectedCountry”。现在转到该属性的 Setter 并将 Itemsource 分配给 MVVM 中的城市组合框。

private Country _SelectedCountry;
        public Country SelectedCountry
        {
            get
            {
                return _SelectedCountry;
            }
            set
            {
                if (_SelectedCountry!= value)
                {
                    _SelectedCountry= value;

                    AllCities = get this from your datasource.
                    RaisePropertyChanged("SelectedCountry");
                }
            }

        }

希望这会对你有所帮助..!

学习愉快..!!

【讨论】:

    猜你喜欢
    • 2017-08-20
    • 2011-11-24
    • 1970-01-01
    • 2021-09-26
    • 2014-08-25
    • 2011-07-11
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多