【问题标题】:WPF MVVM ComboBox with default selected value具有默认选定值的 WPF MVVM 组合框
【发布时间】:2017-03-21 20:24:06
【问题描述】:

我有这个琐碎的问题,但对我没有任何作用:/ 我正在尝试从 viewmodel 设置默认选择的组合框值。代码如下:

public class ItemFilter
{
    public int Id { get; set; }
    public string Name { get; set; }
}

在 ViewModel 中:

public MainViewModel()
{
    SelectedItemFilter = ItemFilters[0];
}

public IList<ItemFilter> ItemFilters
{
    get
    {
        IList<ItemFilter> itemFilter = new List<ItemFilter>();
        itemFilter.Add(new ItemFilter() { Id = 0, Name = "All" });
        itemFilter.Add(new ItemFilter() { Id = 1, Name = "One" });
        itemFilter.Add(new ItemFilter() { Id = 2, Name = "Two" });
        return itemFilter;
    }
}

public ItemFilter SelectedItemFilter
{
    get { return _selectedItemFilter; }
    set { SetProperty(ref _selectedItemFilter, value); }
}

在视图中:

<DataGrid x:Name="DataGridItems"
              EnableRowVirtualization="True"
              ItemsSource="{Binding ItemCollection}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Foo" Binding="{Binding Path=SizeComment}" IsReadOnly="True" Width="120">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding DataContext.ItemFilters, RelativeSource={RelativeSource AncestorType=Window}}"
                                  SelectedItem="{Binding DataContext.SelectedItemFilter, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}"
                                  DisplayMemberPath="Name" />
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

我错过了什么?

【问题讨论】:

    标签: c# wpf xaml mvvm combobox


    【解决方案1】:

    第一个明显的原因是ItemFilters 是在每个请求上创建的。所以SelectedItemFilter = ItemFilters[0]; 创建了一个过滤器列表,然后将第一个分配给SelectedItemFilter。当 ComboBox 请求过滤器列表时,它会得到一个 不同 过滤器列表。所以在ComboBox 项目列表中找不到SelectedItemFilter。有两种解决方案:

    1. 更好的一个 -> 在构造函数中将 ItemFilters 实例化一次。
    2. 如果 1. 不适用,则在 ItemFilter 类中覆盖 Equals()GetHashCode()

    【讨论】:

      【解决方案2】:

      正如@Zbigniew 建议的那样,在属性的getter 中创建一个新列表是一个坏主意。

      MainViewModel 的构造函数将创建一个List&lt;ItemFilter&gt; 并将SelectedItemFilter 设置为该对象中的第一个ItemFilter 对象,然后在解决视图中的绑定时将创建另一个List&lt;ItemFilter&gt;并且 SelectedItemFilter 实例不会出现在这个新列表中。这就是为什么您在 ComboBox 中没有选择任何项目的原因。

      您应该创建一次源集合

      public MainViewModel()
      {
          IList<ItemFilter> itemFilter = new List<ItemFilter>();
          itemFilter.Add(new ItemFilter() { Id = 0, Name = "All" });
          itemFilter.Add(new ItemFilter() { Id = 1, Name = "One" });
          itemFilter.Add(new ItemFilter() { Id = 2, Name = "Two" });
          ItemFilters = itemFilter;
      
          SelectedItemFilter = itemFilter[0];
      }
      
      public IList<ItemFilter> ItemFilters { get; }
      
      public ItemFilter SelectedItemFilter
      {
          get { return _selectedItemFilter; }
          set { SetProperty(ref _selectedItemFilter, value); }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-20
        • 2022-01-14
        相关资源
        最近更新 更多