【问题标题】:How can I control visibility of dynamically generated controls via context menu?如何通过上下文菜单控制动态生成的控件的可见性?
【发布时间】:2014-08-11 18:55:51
【问题描述】:

我有一个 ItemsControl,它绑定到我的 ViewModel 中的属性列表,并使用 DataTemplate,根据属性的类型自动生成适当的控件。

这是 ItemsControl 的代码:

<ItemsControl Grid.Column="0" ItemsSource="{Binding Properties}" >
    <ItemsControl.Resources>
        <DataTemplate x:Key="StringTemplate" DataType="{x:Type ui:ControlStringData}" >
            <xctk:WatermarkTextBox Text="{Binding Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Watermark="{Binding Path=Caption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Margin="5,5,5,5" />
        </DataTemplate>
        <DataTemplate x:Key="DateTimeTemplate" DataType="{x:Type ui:ControlDateTimeData}">
            <xctk:DateTimePicker Value="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Watermark="{Binding Path=Caption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                        Margin="5,5,5,5" />
        </DataTemplate>
        <DataTemplate x:Key="DefaultTemplate" />
    </ItemsControl.Resources>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentControl
                    x:Name="MyContentControl"
                    Content="{Binding}"
                    ContentTemplate="{StaticResource DefaultTemplate}"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=Type}" Value="DateTime">
                    <Setter TargetName="MyContentControl" Property="ContentTemplate"
                                Value="{StaticResource DateTimeTemplate}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Type}" Value="String">
                    <Setter TargetName="MyContentControl" Property="ContentTemplate"
                                Value="{StaticResource StringTemplate}" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

现在给定生成的控件,我想创建一个填充有 Caption 属性和复选框的 ContextMenu,其中 ContextMenu 中的每个项目都绑定到相应控件的可见性。

我当前的代码是一个按钮,可以打开一个上下文菜单,如下所示:

<Button Margin="5,5,5,5" Grid.Column="1" Grid.Row="0" Height="16" Width="16">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <EventTrigger RoutedEvent="Click">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
                                    <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
                                </BooleanAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu />

                </Setter.Value>
            </Setter>
        </Style>
    </Button.Style>
</Button>

如何创建上下文菜单并将选项绑定到可见性?我被卡住了,因为我不确定如何正确设置绑定来执行此操作。

更多细节:

所以在上面的 ItemsControl 中,它绑定到一个名为“Properties”的属性列表,每个元素都在其中实现:

public interface IControlData
{
    string Type { get; set; }
    string Name { get; set; }
    string Caption { get; set; }
    bool Visibility { get; set; }
}

基于类型字符串,我使用上面的数据触发器为该类型生成正确的控件,并将它们放置在模板化为 UniformGrid 的 ItemsControl 中。

现在我想要一个按钮,单击该按钮会显示 ItemsControl 中每个控件的名称列表,并且每个条目都是可检查的,其中可检查状态对应于 ItemsControl 中控件的可见性。

示例:如果 ItemsControl 网格是这样的:

+----------+----------+
| TextBox1 | TextBox2 |
+----------+----------+
| TextBox3 | TextBox4 |
+----------+----------+

然后当我单击按钮时显示的上下文菜单将是:

+---+----------+
| ✓ | TextBox1 |
| ✓ | TextBox2 |
| ✓ | TextBox3 |
| ✓ | TextBox4 |
+---+----------+

如果我单击 ContextMenu 中的一个条目,例如 TextBox4,它会将 TextBox4 的可见性设置为 false,并且项目控件如下所示:

+----------+----------+
| TextBox1 | TextBox2 |
+----------+----------+
| TextBox3 |          |
+----------+----------+

上下文菜单将显示为:

+---+----------+
| ✓ | TextBox1 |
| ✓ | TextBox2 |
| ✓ | TextBox3 |
|   | TextBox4 |
+---+----------+

【问题讨论】:

  • ChangePropertyAction 在父对象或其他对象上从加载的 EventTrigger 切换可见性是一种方法。
  • 我在 MSDN 上查找了这些内容,但对如何实现它有些困惑。无论如何你可以给我一个快速的文章/例子吗? button 和 itemscontrol 都在同一个网格下。
  • 当您说要创建上下文菜单并拥有与可见性相关的选项,您能详细说明一下吗?也许可以帮助您可视化您的整体需求?
  • 我在 OP 中添加了更多细节,如果还有什么需要澄清的请告诉我
  • 好的,我现在明白了很多,我的建议在这种情况下不起作用,我有点偏离了。我即将离开这一天,但我会考虑更多,它需要的不仅仅是 XAML,尽管就像我最初的想法一样。

标签: c# wpf xaml dynamic mvvm


【解决方案1】:

使用 DataTemplateSelector。

该类用于处理基于状态的各种数据模板的选项。

http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector(v=vs.110).aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    相关资源
    最近更新 更多