アプリケーションによって動的に制御されるアイテムの階層コレクションにデータバインドされた動的メニューが機能しています。以下の参照用に、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>
ここで、Microsoft リボン コントロールを使用して、この基礎となるメニュー構造をレンダリングしたいと考えています。最初は、レベル 0 の場合は RibbonTab と RibbonGroup、レベル 1 の場合は 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>
これは簡単に解決できるものかもしれないと感じています。HierarchicalDataTemplate を使用してみましたが、RibbonTab のスタイルが RibbonGroup に適用されているというエラーがありました。
別の関連する質問: AppAction オブジェクトにリボン コントロール スタイルの識別子プロパティ (つまり、ControlStyle [Tab、Group、Button、CheckBox、ComboBox]) がある場合、このプロパティの値に応じて適切なコントロールを動的に作成するのはどれほど簡単でしょうか。それも可能ですか?それとも、複雑なシナリオでは、これらのタスクを担当する後続のビューでリボンの一部を定義し、ビューが表示されているときにそれらを添付する方がよいでしょうか?
編集: 以下は、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();
}
}
単純化された AppActionCollection:
public class AppActionCollection: ObservableCollection<AppAction>
{
}
メニュー ツリーの例は、次の方法で作成できます。
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);
}
}