【问题标题】:How to 2-way bind a Dictionary<enum, bool> to a ListView column in WPF?如何将 Dictionary<enum, bool> 双向绑定到 WPF 中的 ListView 列?
【发布时间】:2011-07-06 17:47:16
【问题描述】:

我有一个这样的类型:

public class EffectViewModel
{
    public string Name { get; set; }
    public string Category { get; set; }

    public Dictionary<ShaderType, bool> ShaderSupport { get; set; }
}

.Name.Category 已绑定到 2 个单独的列,但 ShaderSupport 字典没有。

我不知道如何将字典双向绑定到每个 ShaderType 的单独列。我不知道这些列数是否可以动态完成,但我在 xaml 中对它们进行了硬编码,例如:

<GridViewColumn Width="60" Header="GPU" >
<GridViewColumn Width="60" Header="Pixel" >
...

但现在卡在绑定部分。有什么想法吗?

【问题讨论】:

  • 您需要删除ShaderSupport = { get; set; }中的=

标签: c# .net wpf data-binding listbox


【解决方案1】:
<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding AllEffects}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="NameColumn" />
                        <ColumnDefinition Width="Auto" SharedSizeGroup="CategoryColumn" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Name}" />
                    <TextBlock Text="{Binding Category}" Grid.Column="1" />
                </Grid>
                <ItemsControl ItemsSource="{Binding ShaderSupport}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="60" />
                                </Grid.ColumnDefinitions>
                                <CheckBox Grid.Row="1" IsChecked="{Binding Value, Mode=OneWay}" />
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

这将创建一个没有标题的网格。为了使TwoWay 模式下的复选框绑定用您自己的类型替换字典,KeyValuePair 不允许编写Value 属性,因此不能用于TwoWay 绑定。

请注意,每个EffectVM 的字典中的所有着色器都应该以相同的顺序排列。

【讨论】:

  • @Joan,那么您是否真的需要一个网格,其中行代表Effects,列代表Name, Category, GPU, Pixel, etc.
  • 没错,每个 EffectViewModel 将使用具有相同名称的适当属性填充 .Name、.Category,并且 GPU、Pixel 等列将根据每个 ShaderType 存储在 ShaderSupport 中的值。
  • 所以模糊看起来像“模糊”“平滑” ...然后下一个效果到另一行,等等。
  • @Joan,重写了整个 XAML
  • @Snowbear,现在就试试。现在可以只使用字典吗?它不会崩溃或返回编译错误,对吧?我想测试绑定,如果它读取正确,那么我将切换到我的类型进行写入。
【解决方案2】:

由于字典是一个 IEnumerable,您可以绑定键和值。所说的顺序并不总是与字典一致,所以我会让我的视图模型创建一个包装器 observablecollection

<ListView ItemsSource="{Binding ShaderSupport}">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Width="60" Header="Key" DisplayMemberBinding="{Binding Key}" />
                <GridViewColumn Width="60" Header="Value" DisplayMemberBinding="{Binding Value}" />
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

【讨论】:

  • 这将产生一个两列的 ListView。我相信 OP 想要多个列,每个 ShaderType 在它自己的列中。
  • 是的,我正在尝试在另一种类型中使用 ShaderSupport,因为它用于额外的列。
  • 你试过FrameworkElementFactory吗?它允许您以非常声明性的方式创建数据模板/控制模板。
猜你喜欢
  • 2011-07-06
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2013-05-24
  • 2018-05-22
相关资源
最近更新 更多