2017-07-12 77 views
0

我有这个ListView,其中主要是每个元素由2列DataGrid组成。将DataGridComboBoxColumn绑定到词典

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

我用DataGrid来指定ListView元素1..1运营商/值对。

低于当前图形结果,只是有一个更具体的概念

enter image description here

ListView的每个元素是一个其中的最终生成的查询的子句。每个块都有一个数据类型(int,varchar等)。基于ListView元素数据类型,我想填充数据网格的DataGridComboBoxColumn运算符。

我在视图模型创建这个属性

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

不幸的是(对我:))我得到以下异常

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

但我目前还没有能够映射DataGridComboBoxColumn使用包含在ListView项目中的对象的DataType。我不知道如何修改此约束,以使工作和诚实无论它是否以正确的方式去:

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

回答

1

但我目前无法使用数据类型映射DataGridComboBoxColumn ListView项目中包含的对象

您不能在XAML中执行此操作。 XAML是标记语言,并且使用[DataType]将无法​​解析ListViewItemsSource中的基础对象的类型。这不支持。

你可以使用一个multi value converter,是以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> 
+1

感谢@ MM8听起来不错。我会试一试,并在几个小时内回复给你。再次感谢 – gipinani

+0

我正在通过您的解决方案,无论如何只是一个澄清,以避免误解。 [DataType]只是绑定类的字符串属性,我并不想要推导出对象类型。 – gipinani

+1

没有区别我害怕:) – mm8

相关问题