too*_*too 5 data-binding wpf ribbon
我有一个工作的动态菜单,它是绑定到由应用程序动态控制的分层项目集合的数据.以下参考是WPF声明:
<Menu Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Actions}" Style="{StaticResource ResourceKey=dynamicMenu}">
<Menu.Resources>
<HierarchicalDataTemplate DataType="{x:Type wm:AppAction}" ItemsSource="{Binding Path=Items}">
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="IsCheckable" Value="{Binding IsCheckable}" />
<Setter Property="IsChecked" Value="{Binding IsChecked}" />
<Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={wc:BoolToCollapsedConverter}}"/>
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="Icon" Value="{Binding Image}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Text}" Value="">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator HorizontalAlignment="Stretch" IsEnabled="False"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImageSource}" />
<TextBlock Text="{Binding Text}" />
</StackPanel>
</HierarchicalDataTemplate>
</Menu.Resources>
</Menu>
Run Code Online (Sandbox Code Playgroud)
现在我想使用Microsoft Ribbon控件渲染这个底层菜单结构,最初使用RibbonTab和RibbonGroup为级别0和RibbonButton为级别1(每个选项卡上的单个组)构建它.
不幸的是由于某种原因它没有显示任何东西.这是我到目前为止所说的内容的宣言:
<r:Ribbon Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ribbon" Title="WPF Prototype App" ItemsSource="{Binding Actions}">
<r:Ribbon.Resources>
<DataTemplate DataType="{x:Type wm:AppAction}">
<r:RibbonTab Header="{Binding Text}">
<r:RibbonGroup Header="{Binding Text}" ItemsSource="{Binding Actions}" Width="333">
<r:RibbonGroup.Resources>
<DataTemplate DataType="{x:Type wm:AppAction}">
<r:RibbonButton Label="{Binding Text}" LargeImageSource="{Binding ImageSource}"/>
</DataTemplate>
</r:RibbonGroup.Resources>
</r:RibbonGroup>
</r:RibbonTab>
</DataTemplate>
</r:Ribbon.Resources>
</r:Ribbon>
Run Code Online (Sandbox Code Playgroud)
我觉得这可能是一个简单易解的问题.我尝试使用HierarchicalDataTemplate,但有关RibbonTab应用于RibbonGroup的样式有错误.
另一个相关问题是:如果AppAction对象具有功能区控件样式鉴别器属性(即ControlStyle [Tab,Group,Button,CheckBox,ComboBox]),根据此属性的值动态创建适当的控件是多么容易,或者是它甚至可能吗?或者,对于复杂的场景,只需在后续视图中定义功能区的各个部分来负责这些任务,并在View可见时附加它们更好吗?
编辑:以下是AppAction类简化版的内容:
[ContentProperty("Items")]
public class AppAction: PropertyChangedBase
{
public AppActionCollection Items { get; set; }
ICommand command;
public ICommand Command
{
get { return command; }
set { CheckSet(ref command, value); }
}
string text;
public string Text
{
get { return text; }
set { CheckSet(ref text, value); }
}
Uri imageSource;
public Uri ImageSource
{
get { return imageSource; }
set { image = null; CheckSet(ref imageSource, value); NotifyOfPropertyChange(() => Image); }
}
public AppAction()
{
Items = new AppActionCollection();
}
}
Run Code Online (Sandbox Code Playgroud)
AppActionCollection简化:
public class AppActionCollection: ObservableCollection<AppAction>
{
}
Run Code Online (Sandbox Code Playgroud)
可以通过以下方式创建示例菜单树:
public class TestMenu
{
AppActionCollection menu = new AppActionCollection();
public TestMenu()
{
var m = new AppAction { Text = "File" };
m.Items.Add(new AppAction { Text = "Open" });
m.Items.Add(new AppAction { Text = "Save" });
m.Items.Add(new AppAction { Text = "" });
m.Items.Add(new AppAction { Text = "Exit", Command = ApplicationCommands.Close });
menu.Add(m);
m = new AppAction { Text = "Edit" };
m.Items.Add(new AppAction { Text = "Copy" });
m.Items.Add(new AppAction { Text = "Paste" });
m.Items.Add(new AppAction { Text = "Cut" });
m.Items.Add(new AppAction { Text = "Smile", Command = ApplicationCommands.Close });
menu.Add(m);
}
}
Run Code Online (Sandbox Code Playgroud)
抱歉延迟,我一直在寻找你的问题的解决方案,但不幸的是我没有找到.
HierarchicalDataTemplate不帮助你,因为色带级别不是同一类型.
我认为解决问题的唯一方法是DataTemplate为每个级别创建新的.我知道这不是一个好的解决方案,但我认为这是唯一的方法.如果你找到更好的方法,请分享你的知识并告诉我.
注意:在Menu您可以使用的情况下,HierarchicalDataTemplate因为有一个类型MenuItem.
编辑:
这就是我达到的目的:
MainWindow.xaml.cs:
public ObservableCollection<AppAction> child
{
get
{
ObservableCollection<AppAction> reVal = new ObservableCollection<AppAction>();
reVal.Add(
new AppAction() { Header = "File", Items = new ObservableCollection<AppAction>() {
new AppAction() { Header = "Font", Items = new ObservableCollection<AppAction>() {
new AppAction() { Header = "Arial" },
new AppAction() { Header = "Segoe UI" },
new AppAction() { Header = "Tahoma" } } },
new AppAction() { Header = "Other", Items = new ObservableCollection<AppAction>() {
new AppAction() { Header = "Colse" } } } } });
reVal.Add(
new AppAction() { Header = "View", Items = new ObservableCollection<AppAction>() {
new AppAction() { Header = "A", Items = new ObservableCollection<AppAction>() {
new AppAction() { Header = "AButton" } } },
new AppAction() { Header = "B", Items = new ObservableCollection<AppAction>() {
new AppAction() { Header = "BButton" } } },
new AppAction() { Header = "C", Items = new ObservableCollection<AppAction>() {
new AppAction() { Header = "CButton" } } } } });
return reVal;
}
}
Run Code Online (Sandbox Code Playgroud)
在MainWindow.xaml中:
<Window x:Class="rebbon.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Name="wind">
<Window.Resources>
<DataTemplate x:Key="buttonTempl">
<RibbonButton Label="{Binding Header}"/>
</DataTemplate>
<Style TargetType="RibbonGroup" x:Key="groupStyle">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="ItemsSource" Value="{Binding Items}"/>
<Setter Property="ItemTemplate" Value="{StaticResource buttonTempl}"/>
</Style>
<Style TargetType="RibbonTab" x:Key="tabStyle">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="ItemsSource" Value="{Binding Items}"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource groupStyle}"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Ribbon ItemContainerStyle="{StaticResource tabStyle}" ItemsSource="{Binding ElementName=wind, Path=child}"/>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
结果:

我希望这会对你有所帮助.
我尽力了.