WPF DataGridComboBoxColumn 绑定?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25644003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:27:14  来源:igfitidea点击:

WPF DataGridComboBoxColumn Binding?

c#wpfxamlmvvm

提问by Hardgraf

I'm trying to include a ComboBox column in a WPF datagrid. I'm trying to bind this column to an observable collection in the ViewModel however, at run time the cells remain empty. Datacontext is correct, as all normal columns bind successfully. I want to display 'regionShortCode' in the UI. Here's my xaml:

我正在尝试在 WPF 数据网格中包含一个 ComboBox 列。我试图将此列绑定到 ViewModel 中的一个可观察集合,但是,在运行时单元格保持为空。数据上下文是正确的,因为所有正常列都绑定成功。我想在 UI 中显示“regionShortCode”。这是我的 xaml:

   <DataGridComboBoxColumn Header="Region" DisplayMemberPath="regionShortCode" Width="SizeToHeader">
       <DataGridComboBoxColumn.ElementStyle>
           <Style>
             <Setter Property="ComboBox.ItemsSource" Value="{Binding Path=MembershipsCollection}" />
             </Style>
                </DataGridComboBoxColumn.ElementStyle>
                 <DataGridComboBoxColumn.EditingElementStyle>
              <Style>
                 <Setter Property="ComboBox.ItemsSource" Value="{Binding Path=MembershipsCollection}" />
              </Style>
           </DataGridComboBoxColumn.EditingElementStyle>
     </DataGridComboBoxColumn>

& here is my ObservableCollection declared in the ViewModel. The Collection is populated successfully from a method invoked in the constructor:

& 这是我在 ViewModel 中声明的 ObservableCollection。从构造函数中调用的方法成功填充集合:

private ObservableCollection<tbAccountMembership> _MembershipsCollection;
    public ObservableCollection<tbAccountMembership> MembershipsCollection
    {
        get { return _MembershipsCollection; }
        set
        {
            _MembershipsCollection = value;
            OnPropertyChanged("MembershipsCollection");
        }
    }     

At run time I get:

在运行时我得到:

System.Windows.Data Error: 40 : BindingExpression path error: 'MembershipsCollection' property not found on 'object' ''tbAccountMembership_041E43AFC29975F12C156BA1373ACD47FC07BBE55614E5AF8AD3BBD9F090C133' (HashCode=46247020)'. BindingExpression:Path=MembershipsCollection; DataItem='tbAccountMembership_041E43AFC29975F12C156BA1373ACD47FC07BBE55614E5AF8AD3BBD9F090C133' (HashCode=46247020); target element is 'TextBlockComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')

in the Output window. Why can't the Xaml resolve this binding? Thanks

在输出窗口中。为什么 Xaml 不能解析这个绑定?谢谢

采纳答案by Sheridan

If you want to data bind to a single collection property in the view model from the DataGrid, then your answer to Why can't the Xaml resolve this binding?is because you didn't tell the Framework where to look for the actual property... you'll need to use a [RelativeSource Binding]1. Try this instead:

如果您想将数据绑定到视图模型中的单个集合属性DataGrid,那么您对为什么 Xaml 无法解析此绑定的回答是因为您没有告诉框架在哪里查找实际属性...您需要使用[RelativeSource Binding] 1。试试这个:

<DataGridComboBoxColumn Header="Region" DisplayMemberPath="regionShortCode" 
    Width="SizeToHeader">
    <DataGridComboBoxColumn.ElementStyle>
        <Style>
            <Setter Property="ComboBox.ItemsSource" Value="{Binding 
                DataContext.MembershipsCollection, RelativeSource={RelativeSource 
                AncestorType={x:Type YourViewModelsPrefix:YourViewModel}}}" />
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style>
            <Setter Property="ComboBox.ItemsSource" Value="{Binding 
                DataContext.MembershipsCollection, RelativeSource={RelativeSource 
                AncestorType={x:Type YourViewsPrefix:YourView}}}" />
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

With this Binding Path, the Framework will look outside of the normal DataGrid.DataContextfor a property named MembershipsCollectionin the object that is set as the DataContextof the YourView(clearly this is not the actual name) UserControlor Window. If y our view model is correctly set as the DataContextthen this should work just fine.

有了这个Binding Path,框架看起来正常之外DataGrid.DataContext的命名属性MembershipsCollection在被设置为对象DataContextYourView(显然这是不实际的名称)UserControlWindow。如果您的视图模型正确设置为 ,DataContext那么这应该可以正常工作。

回答by waqar ahmed

You have to provide exact path to the collection to bind with the itemssource of the combobox. for this make your ancestor as your main control i.e window or the usercontrol

您必须提供集合的确切路径以与组合框的 itemssource 绑定。为此,让您的祖先成为您的主要控件,即窗口或用户控件

           <DataGridComboBoxColumn Header="Category"
SelectedValueBinding="{Binding category_cde}"
  SelectedValuePath="category_cde"
DisplayMemberPath="category_dsc">
                        <DataGridComboBoxColumn.ElementStyle>
                            <Style TargetType="ComboBox">
                            <Setter Property="ItemsSource" Value="{Binding Path=CATEGORIES , RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                            </Style>
                        </DataGridComboBoxColumn.ElementStyle>
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="ComboBox">
                            <Setter Property="ItemsSource" Value="{Binding Path=CATEGORIES , RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>

            </DataGrid.Columns>
        </DataGrid>

And here is the collection of categories i defined in code behind where category is some class you can define your own collection

这是我在后面的代码中定义的类别集合,其中类别是一些您可以定义自己的集合的类

 List<Category> m_categories = new List<Category>();
    public List<Category> CATEGORIES
    {
        get { return m_categories; }
        set { m_categories = value; }
    }

回答by AnjumSKhan

A much easier solution with DataGridComboBoxColumn is to set ItemSource binding programmatically in Window class' constructor.

使用 DataGridComboBoxColumn 的一个更简单的解决方案是在 Window 类的构造函数中以编程方式设置 ItemSource 绑定。

<DataGrid x:Name="MembershipGridNormal" AutoGenerateColumns="False" SelectedIndex="0" ItemsSource="{Binding}">
            <DataGrid.Columns>

                <DataGridTextColumn Header="Name" Binding="{Binding Prop1}"/>
                <DataGridTextColumn Header="Value" Binding="{Binding Prop2}"/>
                <DataGridComboBoxColumn x:Name="CmbMemberShips" Header="RawValues" DisplayMemberPath="Name" />

            </DataGrid.Columns>
        </DataGrid>

in code behind

在后面的代码中

public Win32599087()
        {
            InitializeComponent();

            MemberShipGridNormal.DataContext = myCollection;

            Binding b = new Binding();
            b.Source =  myCollection;
            b.Path = new PropertyPath("collectionpropertyname");

            BindingOperations.SetBinding(CmbMemberships, DataGridComboBoxColumn.ItemsSourceProperty, b);
        }