2016-09-22 5 views
0

リボンコントロールなどのDevExpressコントロールを使用してWPFアプリケーションを開発しています。リボンにボタンを動的に配置したいと思っています。私は通常のボタンとドロップダウンボタンの両方をサポートできるようにしたいと思います。バインドされたリボンコントロールのBarButtonItemsとBarSubItem

私は以下のようなことを考えていました。

WPFビュー:

<UserControl.Resources> 
    <DataTemplate x:Key="RibbonCommandTemplate"> 
     <ContentControl> 
      <dxb:BarButtonItem RibbonStyle="All" Content="{Binding Caption}" 
           Command="{Binding (dxr:RibbonControl.Ribbon).DataContext.MenuExecuteCommand, 
             RelativeSource={RelativeSource Self}}" 
           CommandParameter="{Binding}" /> 
     </ContentControl> 
    </DataTemplate> 
</UserControl.Resources> 

<Grid> 
    <DockPanel> 
     <dxr:RibbonControl DockPanel.Dock="Top" RibbonStyle="Office2010"> 
      <dxr:RibbonDefaultPageCategory> 
       <dxr:RibbonPage Caption="Home"> 
        <dxr:RibbonPageGroup Caption="Dynamic Commands" 
             ItemLinksSource="{Binding DynamicCommands}" 
             ItemTemplate="{StaticResource RibbonCommandTemplate}" /> 
       </dxr:RibbonPage> 
      </dxr:RibbonDefaultPageCategory> 
     </dxr:RibbonControl> 
     <Grid/> 
    </DockPanel> 
</Grid> 

ビューモデル:

public class RibbonCommand 
{ 
    public string Caption { get; set; } 
    public int CommandCode { get; set; } 

    public ObservableCollection<RibbonCommand> SubItems { get; set; } 

    public bool HasSubItems 
    { 
     get 
     { 
      if (SubItems != null) 
       return (SubItems.Count > 0); 
      else 
       return false; 
     } 
    } 
} 

[POCOViewModel] 
public class MainViewModel 
{ 
    public ObservableCollection<RibbonCommand> DynamicCommands { get; set; } 

    public MainViewModel() 
    { 
     DynamicCommands = new ObservableCollection<RibbonCommand>(); 

     // Regular buttons. 
     DynamicCommands.Add(new RibbonCommand() { Caption = "Button 1", CommandCode = 1 }); 
     DynamicCommands.Add(new RibbonCommand() { Caption = "Button 2", CommandCode = 2 }); 

     // Drop-down button. 
     RibbonCommand dropDownCommand = new RibbonCommand() { Caption = "Drop-Down", CommandCode = 3 }; 
     dropDownCommand.SubItems = new ObservableCollection<RibbonCommand>(); 
     dropDownCommand.SubItems.Add(new RibbonCommand() { Caption = "Sub-Item 1", CommandCode = 31 }); 
     dropDownCommand.SubItems.Add(new RibbonCommand() { Caption = "Sub-Item 2", CommandCode = 32 }); 
     dropDownCommand.SubItems.Add(new RibbonCommand() { Caption = "Sub-Item 3", CommandCode = 33 }); 
     DynamicCommands.Add(dropDownCommand); 
    } 

    public void MenuExecute(RibbonCommand command) 
    { 
     MessageBox.Show(string.Format("You clicked command with ID: {0} (\"{1}\").", 
         command.CommandCode, command.Caption), "Bound Ribbon Control"); 
    } 
} 

このコードが正常に私は私のDynamicCommandsコレクションに追加された項目とリボンを移入んが、私がサポートしたいと思いますSubItemsコレクション内の項目(上記の例では3番目のボタン)のドロップダウンボタン。

DataTemplateに表示されるコントロールの種類を条件付きで変更する方法はありますか。オブジェクトのHasSubItemsがtrueの場合、リボンに配置されたBarSubItemが必要です。 falseの場合は、BarButtonItemを保持します。

答えて

0

これはむしろUWPより定期的なWPFであり、あなたのサブ項目ののdatacontextsのタイプが異なる場合、あなたは彼らがdoesnの何のためのスコープになりませんRibbonPageGroupのリソースでDataType属性(と複数DataTemplatesを定義することができる場合「tはそれらを)必要とし、そのItemTemplate属性を取り除く:

<dxr:RibbonPageGroup 
    Caption="Dynamic Commands" 
    ItemLinksSource="{Binding DynamicCommands}"> 
    <dxr:RibbonPageGroup.Resources> 
     <DataTemplate DataType="{x:Type local:RibbonCommand}"> 
      <!-- XAML stuff --> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type local:SpecialRibbonCommand}"> 
      <!-- Totally different XAML stuff --> 
     </DataTemplate> 
    </dxr:RibbonPageGroup.Resources> 

    <!-- etc --> 

別のオプションについて、あなたはDataTemplateSelectorを書き、RibbonControl's ToolbarItemTemplateSelector propertyまたはRibbonPageGroup's ItemTemplateSelectorプロパティにそれを与えることができるはずです。

最後に、複数の子コントロールがGridに重なった複雑なDataTemplateと、DataContextのプロパティに基づいて適切なものだけを表示する一連のトリガーを作成します。あなたが扱える2つの異なるオプションしかない場合は、これは最も簡単で簡単なルートかもしれません。

<DataTemplate x:Key="RibbonCommandTemplate"> 
    <Grid> 
     <Label x:Name="OneThing" /> 
     <Label x:Name="AnotherThing" /> 
    </Grid> 
    <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding HasSubItems}" Value="True"> 
      <Setter TargetName="OneThing" Property="Visibility" Value="Collapsed" /> 
      <Setter TargetName="AnotherThing" Property="Visibility" Value="Visible" /> 
     </DataTrigger> 
     <!-- Other triggers for HasSubItems == False, whatever --> 
    </DataTemplate.Triggers> 
</DataTemplate> 

これはかなり粗野なようですが、私はWPFでそれをやっているので、私はそれに鈍感になっています。

0

私はDataTemplateSelectorクラスを使用してこれを行う方法を考え出し:

using System.Windows; 
using System.Windows.Controls; 
using RibbonDynamicButtons.ViewModels; 

namespace RibbonDynamicButtons.Selectors 
{ 
    public class RibbonCommandSelector : DataTemplateSelector 
    { 
     public DataTemplate CommandTemplate { get; set; } 
     public DataTemplate SubCommandTemplate { get; set; } 

     public override DataTemplate SelectTemplate(object item, DependencyObject container) 
     { 
      if(item is RibbonCommand) 
      { 
       RibbonCommand command = (RibbonCommand)item; 
       if (command.HasSubItems) 
        return SubCommandTemplate; 
       else 
        return CommandTemplate; 
      } 

      return base.SelectTemplate(item, container); 
     } 
    } 
} 

次のように私は、XAMLに私のセレクターを追加しました:

<UserControl 
    ... 
    xmlns:Selectors="clr-namespace:RibbonDynamicButtons.Selectors"> 
    <UserControlResources> 
     <DataTemplate x:Key="RibbonSubItemTemplate"> 
      <ContentControl> 
       <dxb:BarButtonItem RibbonStyle="SmallWithText" Content="{Binding Caption}" 
        Command="{Binding (dxr:RibbonControl.Ribbon).DataContext.MenuExecuteCommand, 
         RelativeSource={RelativeSource Self}}" CommandParameter="{Binding}" /> 
      </ContentControl> 
     </DataTemplate> 

     <Selectors:RibbonCommandSelector x:Key="RibbonCommandSelector"> 
      <Selectors:RibbonCommandSelector.CommandTemplate> 
       <DataTemplate> 
        <ContentControl> 
         <dxb:BarButtonItem RibbonStyle="All" 
          Content="{Binding Caption}" 
          Command="{Binding (dxr:RibbonControl.Ribbon).DataContext.MenuExecuteCommand, 
           RelativeSource={RelativeSource Self}}" 
          CommandParameter="{Binding}" /> 
        </ContentControl> 
       </DataTemplate>  
      </Selectors:RibbonCommandSelector.CommandTemplate> 

      <Selectors:RibbonCommandSelector.SubCommandTemplate> 
       <DataTemplate> 
        <ContentControl> 
         <dxb:BarSubItem RibbonStyle="All" Content="{Binding Caption}" 
          ItemLinksSource="{Binding SubItems}" 
          ItemTemplate="{StaticResource RibbonSubItemTemplate}" /> 
        </ContentControl> 
       </DataTemplate> 
      </Selectors:RibbonCommandSelector.SubCommandTemplate> 
     </Selectors:RibbonCommandSelector> 
    </UserControlResources> 

私は私のセレクタにItemTemplateSelectorをバインドRibbonPageGroup:

<dxr:RibbonPageGroup Caption="Dynamic Commands" ItemLinksSource="{Binding DynamicCommands}" 
        ItemTemplateSelector="{StaticResource RibbonCommandSelector}" /> 

View Model I iに何も変更する必要はありません私の元の質問には含まれていません。

関連する問題