Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WPF DataGrid—将类中的字典处理为DataGrid中的列组件_C#_Wpf_Datagrid - Fatal编程技术网

C#WPF DataGrid—将类中的字典处理为DataGrid中的列组件

C#WPF DataGrid—将类中的字典处理为DataGrid中的列组件,c#,wpf,datagrid,C#,Wpf,Datagrid,我试图使用WPF的Datagrid来显示对象的内容。通常,当您试图在类如下所示的情况下显示某些内容时,这是非常简单的: class Employee { public string Name { get; set; } public string Phone { get; set; } public bool Active { get; set; } } class Employee { public Employee() { SecurityAcces

我试图使用WPF的Datagrid来显示对象的内容。通常,当您试图在类如下所示的情况下显示某些内容时,这是非常简单的:

class Employee
{
   public string Name { get; set; }
   public string Phone { get; set; }
   public bool Active { get; set; }
}
class Employee
{
   public Employee()
   {
     SecurityAccesses = new public Dictionary<string, bool>();
   }
   public string Name { get; set; }
   public string Phone { get; set; }
   public bool Active { get; set; }
   public Dictionary<string, bool> SecurityAccesses { get; }
}
但是,假设你有更复杂的事情,比如:

class Employee
{
   public string Name { get; set; }
   public string Phone { get; set; }
   public bool Active { get; set; }
}
class Employee
{
   public Employee()
   {
     SecurityAccesses = new public Dictionary<string, bool>();
   }
   public string Name { get; set; }
   public string Phone { get; set; }
   public bool Active { get; set; }
   public Dictionary<string, bool> SecurityAccesses { get; }
}
class员工
{
公职人员()
{
securityaccess=new public Dictionary();
}
公共字符串名称{get;set;}
公用字符串电话{get;set;}
公共bool活动{get;set;}
公共字典安全访问{get;}
}
如果将其分配给ItemSource,DataGrid将不知道如何处理SecurityAccess,只显示名为SecurityAccess的列,并且单元格将显示为集合

我想做的是让Datagrid意识到它应该让字典的所有键显示列名,当然还有要在Datagrid中显示为复选框的值


我可以通过一些代码来实现这一点,但我正在尝试尽可能多地使用XAML,所以有一种方法可以实现这一点。非常感谢您的推荐。

您能在Datagrid专栏中尝试以下方法吗

<DataGrid.Columns>
     <DataGridTextColumn Header="Key" Binding="{Binding Path=[Key]}" />
      <DataGridTextColumn Header="Value" Binding="{Binding Path=[Value]}" />
</DataGrid.Columns>

能否在Datagrid列中尝试以下方法

<DataGrid.Columns>
     <DataGridTextColumn Header="Key" Binding="{Binding Path=[Key]}" />
      <DataGridTextColumn Header="Value" Binding="{Binding Path=[Value]}" />
</DataGrid.Columns>

您的数据网格可以绑定到可观察的集合。然后,employees DataGrid可以包含DataGridTemplateColumn,该列包含绑定到每个employees的SecurityAccess属性的(子)DataGrid。子DataGrid的数据上下文将是绑定到父DataGrid行的单个员工。比如:

    <DataGrid ItemsSource="{Binding Employees}" ... >
      <DataGrid.Columns>
        <DataGridTextColumn Header="Access" Binding="{Binding Path=Key}" />
        <!-- more Employee columns here -->
        <DataGridTemplateColumn Header="SecurityAccesses">
          <DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                 <DataGrid AutoGenerateColumns="False" CanUserAddRows="False" 
    CanUserDeleteRows="False" ItemsSource="{Binding SecurityAccesses}">
                    <DataGrid.Columns>
         <DataGridTextColumn Header="Access" Binding="{Binding Path=Key}" />
                         <ComboBox Margin="4" ItemsSource="{Binding Value,
                    NotifyOnTargetUpdated=True,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
        ...

...

您的数据网格可以绑定到可观察的集合。然后,employees DataGrid可以包含DataGridTemplateColumn,该列包含绑定到每个employees的SecurityAccess属性的(子)DataGrid。子DataGrid的数据上下文将是绑定到父DataGrid行的单个员工。比如:

    <DataGrid ItemsSource="{Binding Employees}" ... >
      <DataGrid.Columns>
        <DataGridTextColumn Header="Access" Binding="{Binding Path=Key}" />
        <!-- more Employee columns here -->
        <DataGridTemplateColumn Header="SecurityAccesses">
          <DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                 <DataGrid AutoGenerateColumns="False" CanUserAddRows="False" 
    CanUserDeleteRows="False" ItemsSource="{Binding SecurityAccesses}">
                    <DataGrid.Columns>
         <DataGridTextColumn Header="Access" Binding="{Binding Path=Key}" />
                         <ComboBox Margin="4" ItemsSource="{Binding Value,
                    NotifyOnTargetUpdated=True,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
        ...

...

为了跟进那些试图提供帮助的人,我找到了一个例子,说明有人试图完全按照我的意愿行事:

除了用于组成列列表的部分之外,我几乎重用了本例中指定的所有内容。我没有从指定列名称的位置创建单独的字符串列表,而是重用了我的模型,并实现了一个用于从模型中获取字符串列表的转换器。以下是xaml代码:

    <DataGrid ItemsSource="{Binding LeftLegPartsAnomalies}"
          AutoGenerateColumns="False"
          IsReadOnly="{Binding IsFormCanBeAccessed, Converter={StaticResource NegateBooleanConverter}}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding LegPartName}" Header="Name" />
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.HeaderStyle>
                <Style TargetType="DataGridColumnHeader">
                    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    <Setter Property="Margin" Value="0" />
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,
                                    AncestorType={x:Type UserControl}}, 
                                    Path=DataContext.LeftLegPartsAnomalies, 
                                    Converter={StaticResource LegPartsAnomaliesToListAnomaliesNameConverter}}">
                                        <ItemsControl.ItemsPanel>
                                        <ItemsPanelTemplate>
                                            <StackPanel Orientation="Horizontal" />
                                        </ItemsPanelTemplate>
                                    </ItemsControl.ItemsPanel>
                                    <ItemsControl.ItemTemplate>
                                        <DataTemplate>
                                            <Border Width="70">
                                                <TextBlock Text="{Binding}" TextAlignment="Center"/>
                                            </Border>
                                        </DataTemplate>
                                    </ItemsControl.ItemTemplate>
                                </ItemsControl>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGridTemplateColumn.HeaderStyle>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{Binding Anomalies}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal"/>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Border Width="70">
                                    <CheckBox Margin="20,0,0,0" IsChecked="{Binding Spotted}" HorizontalAlignment="Center" />
                                </Border>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

获取字符串列表的“魔法”在LegPartsAnomaliesToListAnomaliesNameConverter中完成:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var listLegParts = value as ObservableCollection<LegPartAnomaly>;

        if (listLegParts == null || listLegParts.Count == 0)
            return null;

        List<string> convertedList = new List<string>();

        foreach (var legPart in listLegParts)
        {
            foreach (var anomaly in legPart.Anomalies)
            {
                if(convertedList.Contains(anomaly.Name))
                {
                    continue;
                }

                convertedList.Add(anomaly.Name);
            }
        }

        return convertedList;
    }
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性) { var listLegParts=作为可观察集合的值; 如果(listLegParts==null | | listLegParts.Count==0) 返回null; List convertedList=新列表(); foreach(listLegParts中的var legPart) { foreach(legPart.异常中的var异常) { if(convertedList.Contains(normal.Name)) { 继续; } convertedList.Add(异常.名称); } } 返回转换列表; } 从我的可观察集合LeftLegPartsAnomalies中,我获得了内部定义的所有异常,并提取了每个异常的名称(一次,不允许重复)。这是转换器的工作

顺便说一下,我知道这与安全访问无关。我使用安全访问示例不是为了深入了解我正在做的事情的细节,但原理是一样的


谢谢你的帮助

为了跟进那些试图帮助我的人,我找到了一个例子,说明有人试图完全按照我的意愿去做:

除了用于组成列列表的部分之外,我几乎重用了本例中指定的所有内容。我没有从指定列名称的位置创建单独的字符串列表,而是重用了m