wpf - 将 WPF DataGridComboBoxColumn 与 MVVM 结合使用 - 绑定(bind)到 ViewModel 中的属性

标签 wpf mvvm wpfdatagrid mvvm-light

我正在使用优秀的 MVVM Light Toolkit。我的 ViewModel 公开:

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);
    }
}

View 有一个 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 有一个 CourtCodes 的 ItemsSource。我希望 CourtType 列成为 CourtCodesTypeCourt 中包含的所有枚举 CourtType 的下拉列表。在我的一生中,我似乎无法用任何东西填充 DataGridComboBoxColumn 。当前失败的尝试正在寻求使用relativesource...我做错了什么?

除了不起作用之外,我看到的两个错误是:

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 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列定义不会以您期望的方式参与逻辑树。这很荒谬,但最后我检查你必须做这样的事情:

<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>

您会注意到我还更改了您的 TextBindingSelectedItemBinding 。我不确定你是否真的想要 TextBinding ,但如果您只想允许用户在列表之间进行选择,则 SelectedItemBinding可能就是您想要的。

此外,您的虚拟机并未完全遵循最佳实践。您正在使用List<T>而不是ObservableCollection<T> ,并且您将其公开为 List<T>而不是更简单的东西,例如 ICollection<T> .

关于wpf - 将 WPF DataGridComboBoxColumn 与 MVVM 结合使用 - 绑定(bind)到 ViewModel 中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3562934/

相关文章:

c# - 绑定(bind)多功能 WPF DataGrid

c# - 使用枚举访问 xaml 中的数组

c# - 使用 await-async 的最佳实践,从哪里开始任务?

c# - 应用程序崩溃后发生的 WPF 事件

c# - Xamarin.Forms 中的 MVVMLight 的 EventToCommand

c# - 根据 ViewModel 属性更改画笔

c# - 用户控制 + ViewModelBase

c# - 如何在MVVM的上下文中处理DataGrid中的页眉单击事件?

wpf - 两列DataGrid : Property name and Property value

WPF 数据网格 : Blank Row Missing