简体   繁体   English

在 DataGrid 中绑定 Combobox

[英]Binding Combobox inside DataGrid

I have a DataGrid with 3 column inside: Name -DataGridTextColumn, Value-DataGridTextColumn, ParamJson - DataGridTemplateColumn with combobox and has a ICollectionView of ParameterGrid as a source.我有一个 DataGrid,里面有 3 列:Name -DataGridTextColumn、Value-DataGridTextColumn、ParamJson - DataGridTemplateColumn 和 combobox 并有一个 ParameterGrid 的 ICollectionView 作为源。

There is a ViewModel that provides ICollectionView of ParameterGrid.有一个 ViewModel 提供了 ParameterGrid 的 ICollectionView。 ParameterGrid contains 4 parameters: Name, Value, ParamJson, SelectedParamJson. ParameterGrid 包含 4 个参数:Name、Value、ParamJson、SelectedParamJson。

I need to handle all rows of DataGrid, so i use the command that get all dataGrid as a Command Parameter and than iterate over DataGrid.Items (I could use directly ICollectionView?).我需要处理DataGrid的所有行,所以我使用将所有dataGrid作为命令参数的命令,而不是遍历DataGrid.Items(我可以直接使用ICollectionView?)。

The question is How to bind properly SelectedItem in Combobox in DataGrid to SelectedParamJson?问题是如何将 DataGrid 中 Combobox 中的 SelectedItem 正确绑定到 SelectedParamJson?

Xaml: Xaml:

<DataGrid Grid.Row="0"
                x:Name="parametersGridView"
                AutoGenerateColumns="False"
                VerticalScrollBarVisibility="Visible"
                CanUserAddRows="False"
                ItemsSource="{Binding PropertiesGrid}"
                Margin="5"
                AlternatingRowBackground="LightGoldenrodYellow">

         <DataGrid.Columns>
            <DataGridTextColumn Header="Name"
                                Binding="{Binding Path=Name}"
                                IsReadOnly="True" />

            <DataGridTextColumn Header="Value"
                                Binding="{Binding Path=Value}" />

            <DataGridTemplateColumn Header="Parameter" >
               <DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                     <ComboBox MinWidth="100"
                               MaxWidth="150"
                               ItemsSource="{Binding Path=ParamsJson}"
                               SelectedItem="{Binding Path=SelectedParamJson, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                               StaysOpenOnEdit="True"
                               IsEditable="True">
                        <ComboBox.ItemTemplate>
                           <DataTemplate>
                              <TextBlock Text="{Binding}" />
                           </DataTemplate>
                        </ComboBox.ItemTemplate>
                     </ComboBox>
                  </DataTemplate>
               </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

         </DataGrid.Columns>
      </DataGrid >     <DataGrid Grid.Row="0"
                x:Name="parametersGridView"
                AutoGenerateColumns="False"
                VerticalScrollBarVisibility="Visible"
                CanUserAddRows="False"
                ItemsSource="{Binding PropertiesGrid}"
                Margin="5"
                AlternatingRowBackground="LightGoldenrodYellow">

         <DataGrid.Columns>
            <DataGridTextColumn Header="Name"
                                Binding="{Binding Path=Name}"
                                IsReadOnly="True" />

            <DataGridTextColumn Header="Value"
                                Binding="{Binding Path=Value}" />

            <DataGridTemplateColumn Header="Parameter" >
               <DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                     <ComboBox ItemsSource="{Binding Path=ParamsJson}"
                               SelectedItem="{Binding Path=SelectedParamJson, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                               StaysOpenOnEdit="True"
                               IsEditable="True">
                        <ComboBox.ItemTemplate>
                           <DataTemplate>
                              <TextBlock Text="{Binding}" />
                           </DataTemplate>
                        </ComboBox.ItemTemplate>
                     </ComboBox>
                  </DataTemplate>
               </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

         </DataGrid.Columns>
      </DataGrid >`

ViewModel视图模型

class DataGridViewModel : DependencyObject
{
    public DataGridViewModel()
    {
        var data = new DataEmulator();
        PropertiesGrid = CollectionViewSource.GetDefaultView(data.GetCommonParameters());
    }

    public ICollectionView PropertiesGrid
    {
        get { return (ICollectionView)GetValue(PropertiesGridProperty); }
        set { SetValue(PropertiesGridProperty, value); }
    }
    public static readonly DependencyProperty PropertiesGridProperty =
        DependencyProperty.Register("PropertiesGrid", typeof(ICollectionView), typeof(DataGridViewModel), new PropertyMetadata(null));

    public ICommand TestCommand
    {
        get
        {
            return new RelayCommand
            {
                ExecuteAction = a =>
                {

                    // here SelectedParamJson should be as Selected in combobox,
                    // but it is always null because of the wrong binding
                },
                CanExecutePredicate = p =>
                {
                    return true;
                }
            };
        }
    }
}
public class ParameterGrid
{
    public string Name { get; set; }
    public string Value { get; set; }
    public List<SamResult> ParamsJson { get; set; }
    public SamResult SelectedParamJson { get; set; }
}

If you want to bind to the SelectedParamJson property that is defined in the same class as the ParamsJson property, you should not set the RelativeSource property to anything at all:如果要绑定到与 ParamsJson 属性相同的ParamsJson中定义的SelectedParamJson属性,则根本不应将RelativeSource属性设置为任何值:

ItemsSource="{Binding Path=ParamsJson}"
SelectedItem="{Binding Path=SelectedParamJson}"

You should also move the ComboBox to the CellEditingTemplate of the DataGridTemplateColumn .您还应该将ComboBox移动到DataGridTemplateColumnCellEditingTemplate中。

The thing is you have to define <DataGridTemplateColumn.CellEditingTemplate> , where you should do all bindings and <DataGridTemplateColumn.CellTemplate> , that present value when the cell is not active.问题是您必须定义<DataGridTemplateColumn.CellEditingTemplate> ,您应该在其中执行所有绑定和<DataGridTemplateColumn.CellTemplate> ,即当单元格不活动时的当前值。

That seems to be strange that you could not bind everything inside <DataGridTemplateColumn.CellTemplate> , because you have to do an additional klick to activate combobox.您无法绑定<DataGridTemplateColumn.CellTemplate>中的所有内容,这似乎很奇怪,因为您必须额外单击才能激活 combobox。

Xaml that works for me: Xaml 对我有用:

    <DataGridTemplateColumn Header="Parameter" >

       <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
             <TextBlock Text="{Binding Path=SelectedParamJson}" />
          </DataTemplate>
       </DataGridTemplateColumn.CellTemplate>

       <DataGridTemplateColumn.CellEditingTemplate>
          <DataTemplate>
             <ComboBox MinWidth="100"
                       MaxWidth="150"
                       ItemsSource="{Binding Path=ParamsJson}"
                       SelectedItem="{Binding Path=SelectedParamJson}"
                       StaysOpenOnEdit="True"
                       IsEditable="True">
                <ComboBox.ItemTemplate>
                   <DataTemplate>
                      <TextBlock Text="{Binding}" />
                   </DataTemplate>
                </ComboBox.ItemTemplate>
             </ComboBox>
          </DataTemplate>
       </DataGridTemplateColumn.CellEditingTemplate>

    </DataGridTemplateColumn>

your ancestor is not the datagrid its the datarow you want to get the datacontext from.您的祖先不是数据网格,而是您要从中获取数据上下文的数据行。

so you made a collection view of some source collection like list, this means every row in your Datagrid repesents a IJsonObject Object and there you should have your Collection for the ComboBox Column defined.所以你做了一个像列表这样的源集合的集合视图,这意味着你的Datagrid中的每一行都代表一个IJsonObject Object,你应该在那里定义你的ComboBox列的集合。 Like a List that you can bind to the Column and in Turn you can have a IJsonProperty field that you can bind to the selected Item.就像可以绑定到 Column 的 List 一样,在 Turn 中,您可以拥有一个 IJsonProperty 字段,您可以将其绑定到选定的 Item。

So then you should get a Combobox filled with yout List Items and if you select one of them the IJsonProerty Field will be set to the selected Item.那么你应该得到一个 Combobox 填充你的列表项,如果你 select 其中之一,IJsonProerty 字段将设置为所选项目。

I hope its understandable since I dont really got a code snippet right now.我希望它可以理解,因为我现在还没有真正的代码片段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM