简体   繁体   English

将DataGridComboBoxColumn绑定到字典

[英]Binding DataGridComboBoxColumn to a Dictionary

I have this ListView , where principally each element consists of a 2 columns DataGrid . 我有这个ListView ,其中每个元素主要由2列DataGrid

<ListView Name="SelectedWhereItemListView" 
          ItemsSource="{Binding AddedWhereItems}"
          VerticalContentAlignment="Top">
   <ListView.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel Orientation="Horizontal" />
      </ItemsPanelTemplate>
   </ListView.ItemsPanel>
   <ListView.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Vertical">
            <TextBlock Text="{Binding TableName}" />
            <TextBlock Text="{Binding ColumnName}" />
            <DataGrid SelectionMode="Single" AutoGenerateColumns="False" ItemsSource="{Binding WhereFieldCondition}">
               <DataGrid.Columns>
                  <DataGridComboBoxColumn Width="Auto" Header="{lex:Loc Key=Operator}" SelectedValueBinding="{Binding Operator}">
                     <DataGridComboBoxColumn.ElementStyle>
                        <Style TargetType="{x:Type ComboBox}">
                           <Setter Property="ItemsSource" Value="{Binding Path=DataContext.WhereFieldConditions[DataType], RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                        </Style>
                     </DataGridComboBoxColumn.ElementStyle>
                     <DataGridComboBoxColumn.EditingElementStyle>
                        <Style TargetType="{x:Type ComboBox}">
                           <Setter Property="ItemsSource" Value="{Binding Path=DataContext.WhereFieldConditions[DataType], RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                        </Style>
                     </DataGridComboBoxColumn.EditingElementStyle>
                  </DataGridComboBoxColumn>
                  <DataGridTextColumn Width="Auto" Header="{lex:Loc Key=Value}" Binding="{Binding Value}" />
               </DataGrid.Columns>
            </DataGrid>
         </StackPanel>
      </DataTemplate>
   </ListView.ItemTemplate>
</ListView>

I use the DataGrid to specify 1..n Operator / Value pairs for the ListView element. 我使用DataGridListView元素指定1..n运算符/值对。

Below the current graphical result, just to have a more concrete idea 在当前图形结果下方,只是有一个更具体的想法

在此处输入图片说明

Each element of the ListView is a where clause of an eventually generated query. ListView每个元素都是最终生成的查询的where子句。 Each block has a datatype (int, varchar, etc). 每个块都有一个数据类型(int,varchar等)。 Based on the ListView element datatype I'd like to fill the DataGridComboBoxColumn Operator of the datagrid. 基于ListView元素数据类型,我想填充datagrid的DataGridComboBoxColumn运算符。

I've created this property in the ViewModel 我已经在ViewModel中创建了此属性

public Dictionary<string, ObservableCollection<string>> WhereFieldConditions
{
    get
    {
        if (_whereFieldconditions == null)
        {
            _whereFieldconditions = new Dictionary<string, ObservableCollection<string>>();
            _whereFieldconditions.Add("int", new ObservableCollection<string>(new string[] { "<", ">", "=", "!=" }.ToList<string>()));
            _whereFieldconditions.Add("decimal", new ObservableCollection<string>(new string[] { "<", ">", "=", "!=" }.ToList<string>()));
            _whereFieldconditions.Add("nvarchar", new ObservableCollection<string>(new string[] { "=", "like" }.ToList<string>()));
            _whereFieldconditions.Add("varchar", new ObservableCollection<string>(new string[] { "=", "like" }.ToList<string>()));
            _whereFieldconditions.Add("char", new ObservableCollection<string>(new string[] { "=", "like" }.ToList<string>()));
            _whereFieldconditions.Add("datetime", new ObservableCollection<string>(new string[] { "<", ">", "=" }.ToList<string>()));

        }
        return _whereFieldconditions;
    }
}

Unfortunately (for me :)) I obtain the following exception 不幸的是(对我来说:))我得到以下异常

System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type 'ObservableCollection`1') from 'WhereFieldConditions' (type 'Dictionary`2'). BindingExpression:Path=DataContext.WhereFieldConditions[.DataType]; DataItem='StockageQueryEditorView' (Name=''); target element is 'TextBlockComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable') TargetInvocationException:'System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at MS.Internal.Data.PropertyPathWorker.GetValue(Object item, Int32 level)
   at MS.Internal.Data.PropertyPathWorker.RawValue(Int32 k)'

But I'm currently not able to map the DataGridComboBoxColumn using the DataType of the object contained into the ListView item. 但是我目前无法使用包含在ListView项目中的对象的DataType来映射DataGridComboBoxColumn I don't know how to modify this binding in order to make it working and honestly neither if it's the right way to go: 我不知道如何修改此绑定以使其正常工作,老实说,这都不是正确的方法:

Binding Path=DataContext.WhereFieldConditions[DataType], RelativeSource={RelativeSource AncestorType={x:Type Window}

But I'm currently not able to map the DataGridComboBoxColumn using the DataType of the object contained into the ListView item 但是我目前无法使用包含在ListView项目中的对象的DataType来映射DataGridComboBoxColumn

You can't do this in XAML. 您无法在XAML中执行此操作。 XAML is a markup language and won't be able to resolve the type of the underlying object in the ItemsSource of the ListView using [DataType] . XAML是一种标记语言,无法使用[DataType]解析ListViewItemsSource中基础对象的[DataType] This is not supported. 不支持。

You could use a multi value converter that takes the Dictionary<string, ObservableCollection<string>> and the data object and returns the correct ObservableCollection<string> based on the type of the object: 您可以使用多值转换器 ,该转换器使用Dictionary<string, ObservableCollection<string>>和数据对象,并根据对象的类型返回正确的ObservableCollection<string>

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="ItemsSource">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource conv}">
                <Binding Path="DataContext.WhereFieldConditions" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
                <Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType=ListViewItem}" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Style>

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

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