将WPF DataGridComboBoxColumn与MVVM一起使用-绑定到ViewModel中的属性 [英] Using WPF DataGridComboBoxColumn with MVVM - Binding to Property in ViewModel

查看:518
本文介绍了将WPF DataGridComboBoxColumn与MVVM一起使用-绑定到ViewModel中的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用出色的MVVM Light Toolkit.我的ViewModel公开了:

I'm using the excellent MVVM Light Toolkit. My ViewModel exposes:

public const string CourtCodesTypeCourtPropertyName = "CourtCodesTypeCourt";
private List<CourtType> _courtCodesTypes = new List<CourtType>();
public List<CourtType> CourtCodesTypeCourt
{
    get
    {
        return _courtCodesTypes;
    }

    set
    {
        if (_courtCodesTypes == value)
        {
            return;
        }

        var oldValue = _courtCodesTypes;
        _courtCodesTypes = value;

        // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
        RaisePropertyChanged(CourtCodesTypeCourtPropertyName, oldValue, value, true);
    }
}

public const string CourtCodesPropertyName = "CourtCodes";
private List<Court> _courtCodes = null;
public List<Court> CourtCodes
{
    get
    {
        return _courtCodes;
    }

    set
    {
        if (_courtCodes == value)
        {
            return;
        }

        var oldValue = _courtCodes;
        _courtCodes = value;

        // Update bindings and broadcast change using GalaSoft.Utility.Messenging
        RaisePropertyChanged(CourtCodesPropertyName, oldValue, value, true);
    }
}

该视图具有一个DataGrid:

The View has a DataGrid:

<DataGrid
      ItemsSource="{Binding CourtCodes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
      AutoGenerateColumns="False"
      AlternatingRowBackground="{DynamicResource OffsetBrown}"
      AlternationCount="1" Margin="45,0">
   <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding Abbreviation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
         Header="Abbreviation"
         Width="25*" />
    <DataGridTextColumn Binding="{Binding FullName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
         Header="Court"
         Width="75*" />
    <DataGridComboBoxColumn Header="CourtType" 
         ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CourtCodesTypeCourt} TextBinding="{Binding CourtTypeDescription}""/>
   </DataGrid.Columns>
  </DataGrid>

如您所见,DataGrid具有ItemsCodes的ItemsSource.我希望CourtType列是包含在CourtCodesTypeCourt中的所有枚举CourtType的下拉列表.在我的一生中,我似乎无法用任何东西填充DataGridComboBoxColumn.当前失败的尝试是希望使用RelativeSource ...我在做什么错了?

The DataGrid has an ItemsSource, as you can see, of CourtCodes. I want the CourtType column to be a drop down of all enumerated CourtTypes that are contained within CourtCodesTypeCourt. For the life of me, I can't seem to populate the DataGridComboBoxColumn with anything. The current failed attempt is looking to use RelativeSource... what am I doing wrong?

除了无法正常工作外,我看到的两个错误是:

In addition to not working, the two errors I see are:

System.Windows.Data错误:4:无法 查找参考的绑定来源 'RelativeSource FindAncestor, AncestorType ='System.Windows.Window', AncestorLevel ='1''. BindingExpression:Path = DataContext.CourtCodesTypeCourt; DataItem = null;目标元素是 'DataGridComboBoxColumn' (HashCode = 38771709);目标物业 是"ItemsSource"(类型为"IEnumerable")

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=DataContext.CourtCodesTypeCourt; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=38771709); target property is 'ItemsSource' (type 'IEnumerable')

System.Windows.Data错误:40: BindingExpression路径错误: 'CourtCodesTypeCourt'属性不是 在对象"法院"上找到 (HashCode = 38141773)". BindingExpression:Path = CourtCodesTypeCourt.CourtTypeDescription; DataItem ='法院'(HashCode = 38141773); 目标元素是"ComboBox" (名称='');目标属性是文本" (类型为字符串")

System.Windows.Data Error: 40 : BindingExpression path error: 'CourtCodesTypeCourt' property not found on 'object' ''Court' (HashCode=38141773)'. BindingExpression:Path=CourtCodesTypeCourt.CourtTypeDescription; DataItem='Court' (HashCode=38141773); target element is 'ComboBox' (Name=''); target property is 'Text' (type 'String')

推荐答案

DataGrid列定义不按照您期望的方式参与逻辑树.这太荒谬了,但最后我检查了您是否必须执行以下操作:

DataGrid column definitions don't participate in the logical tree in the way you would expect. It's ridiculous, but last I checked you have to do something like this:

<DataGridComboBoxColumn Header="CourtType" SelectedItemBinding="{Binding Type}">
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CourtCodesTypeCourt}"/>
            <Setter Property="IsReadOnly" Value="True"/>
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CourtCodesTypeCourt}"/>
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

您会注意到我也将您的TextBinding更改为SelectedItemBinding.我不确定您是否确实打算使用TextBinding,但是如果您只想允许用户在列表之间进行选择,那么SelectedItemBinding可能就是您想要的.

You'll notice I've also changed your TextBinding to a SelectedItemBinding. I'm not sure if you actually intended a TextBinding, but if you just want to allow the user to select between the list, then SelectedItemBinding is likely what you want.

此外,您的VM并不完全遵循最佳实践.您使用的是List<T>而不是ObservableCollection<T>,并且将其公开为List<T>,而不是像ICollection<T>这样的简单名称.

Also, your VMs don't exactly follow best practices. You're using List<T> instead of ObservableCollection<T>, and you're exposing it as List<T> rather than something simpler such as ICollection<T>.

这篇关于将WPF DataGridComboBoxColumn与MVVM一起使用-绑定到ViewModel中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆