【问题标题】:WPF: ContextMenu MenuItem from DataContext/ItemsSource?WPF:来自 DataContext/ItemsSource 的 ContextMenu MenuItem?
【发布时间】:2017-06-26 19:28:44
【问题描述】:

我正在构建一个简单的应用程序来存储电视节目。我有一个用于节目的视频类,其中包含一些字段和属性,包括对 VideoSeason 类型对象的一个​​引用,代表电视节目的季节。 Video 对象的对应 UI 元素是 Button,带有带有一些操作的 ContextMenu

我想在ContextMenu 中创建一个MenuItem,其中包含添加到电视节目中的所有季节,以子菜单的形式表示。我知道要做到这一点,我必须将ObservableCollection 季节标记为MenuItem 季节的ItemsSource,并指出MenuItem 内的任何子菜单都绑定到VideoSeason 内的属性SeasonNumber

我的问题是我真的不知道如何在 XAML 中绑定这些子菜单项,如果这实际上可能的话。我已经尝试了一些选项(例如,WPF ContextMenu itemtemplate, menuitem inside menuitemBinding WPF ContextMenu MenuItem to UserControl Property vs ViewModel Property),但我只想绑定我的 MenuItem,而不是整个 CntextMenu

这是 Video 类的相关部分:

    public string Name { get; set; }       
    public int NextEpisode { get; set; }
    public ObservableCollection<VideoSeason> Seasons { get; set; }

这里是 XAML 代码的相关部分:

       <ScrollViewer>
        <StackPanel Name="filmHolder" 
          Grid.Row="1" Grid.Column="0" >
            <ItemsControl Name="VideoUIElment">
                <ItemsControl.ItemTemplate>
                    <DataTemplate x:Uid="videoTemplate">
                        <Border CornerRadius="10" Padding="10, 10" Background="Silver">
                          <Button Name="filmLabel" Content="{Binding Name}"  FontSize="30" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center"
                              Click="FilmLabel_Click" BorderThickness="0">
                                <Button.ContextMenu>
                                    <ContextMenu Name="LocalMenu">
                                        <MenuItem Header="Rename"/>
                                        <MenuItem Header="Delete"/>
                                        <MenuItem Header="Add New Season" Name="NewSeason" Click="NewSeason_Click"/>
                                        <MenuItem Header="Seasons" ItemsSource="{Binding Seasons}">
                                            <!--<MenuItem.ItemTemplate This is one of the things I tried in vain>
                                                    <DataTemplate>
                                                    <MenuItem Header="{Binding SeasonNumber}"/>
                                                    </DataTemplate>
                                            </MenuItem.ItemTemplate>-->
                                        </MenuItem>
                                    </ContextMenu>
                                </Button.ContextMenu>
                            </Button>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>
    </ScrollViewer>

可以看出,有问题的部分嵌套在属于Video UI的DataTemplate中,这可能是问题的原因,但我不确定。

【问题讨论】:

    标签: wpf xaml custom-contextmenu


    【解决方案1】:

    如果您将ItemsControlItemsSource 属性绑定到IEnumerable&lt;Video&gt;,这应该可以工作:

    <ItemsControl Name="VideoUIElment" ItemsSource="{Binding Videos}">
        <ItemsControl.ItemTemplate>
            <DataTemplate x:Uid="videoTemplate">
                <Border CornerRadius="10" Padding="10, 10" Background="Silver">
                    <Button Name="filmLabel" Content="{Binding Name}"  FontSize="30" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center"
                                  Click="FilmLabel_Click" BorderThickness="0">
                        <Button.ContextMenu>
                            <ContextMenu Name="LocalMenu">
                                <MenuItem Header="Rename"/>
                                <MenuItem Header="Delete"/>
                                <MenuItem Header="Add New Season" Name="NewSeason" Click="NewSeason_Click"/>
                                <MenuItem Header="Seasons" ItemsSource="{Binding Seasons}">
                                    <MenuItem.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding SeasonNumber}"/>
                                        </DataTemplate>
                                    </MenuItem.ItemTemplate>
                                </MenuItem>
                            </ContextMenu>
                        </Button.ContextMenu>
                    </Button>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    确保SeasonNumberVideoSeason 类的公共属性。

    【讨论】:

    • 谢谢!你能解释一下这实际上是如何工作的吗?我必须承认,我知道 IEnumerables 是 foreach 循环只能工作的必要元素。我找到了关于 IEnumerable 本身的文章,但我仍然会对它在这种特殊情况下的工作原理感兴趣。
    • 您可以将 ItemsControl 的 ItemsSource 属性绑定或设置到任何实现 IEnumerable 接口的对象。 ItemsControl 枚举源集合并将 ItemTemplate 应用于每个单独的项目。
    • 我明白了。再次感谢你。以前我没有按照这些思路进行思考,但今天我学到了一些关于 C# 实际工作原理的新知识。
    • 最后一件事我不明白:我还连接了一个 ComboBox,但在这种情况下,我不需要 IEnumerable。我刚刚在后面的代码中使用了 SeasonSelector.ItemsSource = vid.Seasons,(其中 vid 是视频,SS 是 ComboBox),它运行良好。那么,这两件事是否使用不同的方法生成 UI 元素?
    • 您可以将 ItemsSource 属性绑定或设置为 IEnumerable。 vid.Seasons 返回一个 IEnumerable。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多