Microsoft WPF功能区(2010年10月发行版) - 绑定到内容

时间:2010-11-22 17:15:57

标签: .net wpf ribbon ribbon-control

我的应用程序中有Microsoft Ribbon的实例,我正在尝试将RibbonGroup的内容绑定到我的ViewModel中的图像集合,其方式是:(a)图像显示为RibbonButton的大图像和(b)当用户单击其中一个RibbonButton控件时,相应的图像被设置为集合的CurrentItem(当前是EntityCollection)。

我尝试了各种方法,基于以下内容......

    <DataTemplate x:Key="viewButtonTemplate">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <ribbon:RibbonButton Grid.Row="0" Label="{Binding Path=ImageType.Description}"
                                                 LargeImageSource="{Binding Path=ImageData, Converter={StaticResource BinaryJpegToImageSourceConverter}}"
                                                 Command=""/>
            <Image Grid.Row="0" MaxWidth="30" Source="{Binding Path=ImageData, Converter={StaticResource BinaryJpegToImageSourceConverter}}"/>
            <TextBlock Grid.Row="1" Text="{Binding Path=ImageType.Description}"/>
        </Grid>
    </DataTemplate>


<ribbon:RibbonGroup Header="View">
    <ListBox Name="imageList" Background="Transparent" BorderThickness="0" Focusable="True" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=Images}" ItemTemplate="{StaticResource viewButtonTemplate}" ScrollViewer.VerticalScrollBarVisibility="Hidden">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
    </ListBox>
</ribbon:RibbonGroup>

但一切都无济于事!我根本无法让RibbonButton按照我的意愿行事。注意:模板中的附加图像控件实际上允许它工作;它似乎与让ListView识别RibbonButton的点击有关。

有什么建议吗?

1 个答案:

答案 0 :(得分:5)

我已经实现了一个使用带有MVVM模式的Ribbon控件的WPF应用程序,但我的方法是创建一组绑定功能区的导航界面。我还利用功能区元素的样式来控制数据绑定,我相信这可以帮助您完成所需的工作。

将Ribbon控件绑定到视图模型后,可以填充选项卡及其子组,以便渲染要显示的图像,然后在希望执行的视图模型上指定ICommand。组被选中。此命令将调用方法来设置集合的当前项。

功能区控件样式:

<Window.Resources>

    <!-- RibbonMenuItem -->
    <Style TargetType="{x:Type ribbon:RibbonMenuItem}">
        <Setter Property="Header" Value="{Binding Header}" />
        <Setter Property="ImageSource" Value="{Binding Image}" />
        <Setter Property="ribbon:RibbonControlService.ToolTipTitle" Value="{Binding ToolTipTitle}" />
        <Setter Property="ribbon:RibbonControlService.ToolTipDescription" Value="{Binding ToolTipDescription}" />
        <Setter Property="ribbon:RibbonControlService.ToolTipImageSource" Value="{Binding ToolTipImage}" />
        <Setter Property="ribbon:RibbonControlService.ToolTipFooterTitle" Value="{Binding ToolTipFooterTitle}" />
        <Setter Property="ribbon:RibbonControlService.ToolTipFooterDescription" Value="{Binding ToolTipFooterDescription}" />
        <Setter Property="ribbon:RibbonControlService.ToolTipFooterImageSource" Value="{Binding ToolTipFooterImage}" />
        <Setter Property="KeyTipService.KeyTip" Value="{Binding KeyTip}" />
        <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
        <Setter Property="Command" Value="{Binding Command}" />
        <Setter Property="IsCheckable" Value="{Binding IsCheckable}" />
        <Setter Property="IsChecked" Value="{Binding IsChecked}" />
        <Setter Property="CanUserResizeVertically" Value="{Binding IsVerticallyResizable}" />
        <Setter Property="CanUserResizeHorizontally" Value="{Binding IsHorizontallyResizable}" />
        <Setter Property="ItemsSource" Value="{Binding Items}" />

        <Style.Triggers>
            <DataTrigger Binding="{Binding Command}" Value="{x:Null}">
                <Setter Property="Command" Value="{x:Null}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding CommandParameter}" Value="{x:Null}">
                <Setter Property="CommandParameter" Value="{x:Null}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Image}" Value="{x:Null}">
                <Setter Property="ImageSource" Value="{x:Null}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding ToolTipImage}" Value="{x:Null}">
                <Setter Property="ribbon:RibbonControlService.ToolTipImageSource" Value="{x:Null}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding ToolTipFooterImage}" Value="{x:Null}">
                <Setter Property="ribbon:RibbonControlService.ToolTipFooterImageSource" Value="{x:Null}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <!-- RibbonSplitMenuItem -->
    <Style TargetType="{x:Type ribbon:RibbonSplitMenuItem}" BasedOn="{StaticResource {x:Type ribbon:RibbonMenuItem}}">
        <Setter Property="HeaderQuickAccessToolBarId" Value="{Binding Command}" />
        <Setter Property="QuickAccessToolBarId" Value="{Binding DropDownButtonData.Command}" />
        <Setter Property="HeaderKeyTip" Value="{Binding KeyTip}" />
        <Setter Property="KeyTip" Value="{Binding DropDownButtonData.KeyTip}" />
        <Setter Property="DropDownToolTipTitle" Value="{Binding DropDownButtonData.ToolTipTitle}" />
        <Setter Property="DropDownToolTipDescription" Value="{Binding DropDownButtonData.ToolTipDescription}" />
        <Setter Property="DropDownToolTipImageSource" Value="{Binding DropDownButtonData.ToolTipImage}" />
        <Setter Property="DropDownToolTipFooterTitle" Value="{Binding DropDownButtonData.ToolTipFooterTitle}" />
        <Setter Property="DropDownToolTipFooterDescription" Value="{Binding DropDownButtonData.ToolTipFooterDescription}" />
        <Setter Property="DropDownToolTipFooterImageSource" Value="{Binding DropDownButtonData.ToolTipFooterImage}" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding DropDownButtonData.ToolTipImage}" Value="{x:Null}">
                <Setter Property="DropDownToolTipImageSource" Value="{x:Null}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding DropDownButtonData.ToolTipFooterImage}" Value="{x:Null}">
                <Setter Property="DropDownToolTipFooterImageSource" Value="{x:Null}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <!-- RibbonApplicationMenuItem -->
    <Style TargetType="{x:Type ribbon:RibbonApplicationMenuItem}" BasedOn="{StaticResource {x:Type ribbon:RibbonMenuItem}}">
        <Style.Triggers>
            <Trigger Property="Level" Value="Middle">
                <Setter Property="ImageSource" Value="{Binding Image}" />
                <Setter Property="KeyTipService.KeyTip" Value="{Binding KeyTip}" />
                <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
                <Setter Property="Command" Value="{Binding Command}" />
                <Setter Property="Header" Value="{Binding Header}" />
            </Trigger>
        </Style.Triggers>
    </Style>

    <!-- RibbonApplicationSplitMenuItem -->
    <Style TargetType="{x:Type ribbon:RibbonApplicationSplitMenuItem}" BasedOn="{StaticResource {x:Type ribbon:RibbonSplitMenuItem}}" />

    <!-- RibbonTab -->
    <Style TargetType="{x:Type ribbon:RibbonTab}">
        <Setter Property="Header" Value="{Binding Header}" />
        <Setter Property="ItemsSource" Value="{Binding Groups}" />
    </Style>

    <!-- RibbonGroupItem -->
    <Style TargetType="{x:Type ribbon:RibbonButton}" x:Key="RibbonGroupItemButton">
        <Setter Property="Label" Value="{Binding Label}" />
        <Setter Property="LargeImageSource" Value="{Binding LargeImage}" />
        <Setter Property="SmallImageSource" Value="{Binding SmallImage}" />
        <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
        <Setter Property="Command" Value="{Binding Command}" />

        <Style.Triggers>
            <DataTrigger Binding="{Binding LargeImage}" Value="{x:Null}">
                <Setter Property="LargeImageSource" Value="{x:Null}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding SmallImage}" Value="{x:Null}">
                <Setter Property="SmallImageSource" Value="{x:Null}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <DataTemplate DataType="{x:Type ribbon:RibbonControl}"  x:Key="RibbonGroupItemTemplate">
        <ribbon:RibbonButton Style="{StaticResource RibbonGroupItemButton}" />
    </DataTemplate>

    <!-- RibbonGroup -->
    <Style TargetType="{x:Type ribbon:RibbonGroup}">
        <Setter Property="Header" Value="{Binding Header}" />
        <Setter Property="ItemsSource" Value="{Binding Items}" />
        <Setter Property="ItemTemplate" Value="{StaticResource RibbonGroupItemTemplate}" />
    </Style>

</Window.Resources>

视图模型公开的属性(数据绑定):

#region MenuItems
/// <summary>
/// Gets the application menu items.
/// </summary>
/// <value>
/// A <see cref="SelectableObservableCollection{IMenuItem}"/> that contains 
/// the application menu items. The default value is an <i>empty</i> collection.
/// </value>
public SelectableObservableCollection<IMenuItem> MenuItems
{
    get
    {
        if (_viewModelMenuItems == null)
        {
            _viewModelMenuItems = new SelectableObservableCollection<IMenuItem>();
        }
        return _viewModelMenuItems;
    }
}
private SelectableObservableCollection<IMenuItem> _viewModelMenuItems;
#endregion

#region Tabs
/// <summary>
/// Gets the application navigation tabs.
/// </summary>
/// <value>
/// A <see cref="SelectableObservableCollection{INavigationTab}"/> that contains 
/// the application navigation tabs. The default value is an <i>empty</i> collection.
/// </value>
public SelectableObservableCollection<INavigationTab> Tabs
{
    get
    {
        if (_viewModelTabs == null)
        {
            _viewModelTabs = new SelectableObservableCollection<INavigationTab>();
        }
        return _viewModelTabs;
    }
}
private SelectableObservableCollection<INavigationTab> _viewModelTabs;
#endregion

查看(功能区XAML):

<ribbon:Ribbon Grid.Row="0" ItemsSource="{Binding Path=Tabs}">

    <ribbon:Ribbon.ApplicationMenu>
        <ribbon:RibbonApplicationMenu 
            Margin="0, 5, 0, 0"
            LargeImageSource="/MyApp;component/Resources/Images/ApplicationMenu.png" 
            SmallImageSource="/MyApp;component/Resources/Icons/ApplicationMenu.png" 
            ItemsSource="{Binding Path=MenuItems}" 
        >
            <ribbon:RibbonApplicationMenu.FooterPaneContent>
                <DockPanel LastChildFill="False">
                    <ribbon:RibbonButton 
                        DockPanel.Dock="Right" Margin="2" BorderBrush="#B8114EAF" 
                        Command="{Binding Path=Shutdown}"
                        Label="Exit" ToolTipTitle="Quit application" KeyTip="X" 
                        SmallImageSource="/MyApp;component/Resources/Icons/Exit.png" />
                </DockPanel>
            </ribbon:RibbonApplicationMenu.FooterPaneContent>

        </ribbon:RibbonApplicationMenu>
    </ribbon:Ribbon.ApplicationMenu>

</ribbon:Ribbon>

导航界面:

public interface IMenuItem : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
    #region Command
    /// <summary>
    /// Gets or sets the command associated with the menu item.
    /// </summary>
    /// <value>
    /// The <see cref="ISurrogateCommand"/> associated with the menu item.
    /// </value>
    ISurrogateCommand Command
    {
        get;
        set;
    }
    #endregion

    #region CommandParameter
    /// <summary>
    /// Gets or sets the parameter to pass to the command associated with the menu item.
    /// </summary>
    /// <value>
    /// The parameter to pass to the <see cref="Command"/> associated with the menu item.
    /// </value>
    object CommandParameter
    {
        get;
        set;
    }
    #endregion

    #region Header
    /// <summary>
    /// Gets or sets the item that labels the menu item.
    /// </summary>
    /// <value>
    /// The item that labels the menu item.
    /// </value>
    object Header
    {
        get;
        set;
    }
    #endregion

    #region Image
    /// <summary>
    /// Gets or sets the image that is displayed on the menu item.
    /// </summary>
    /// <value>
    /// The <see cref="ImageSource"/> that is displayed on the menu item.
    /// </value>
    ImageSource Image
    {
        get;
        set;
    }
    #endregion

    #region IsCheckable
    /// <summary>
    /// Gets or sets a value that indicates whether the menu item can be checked.
    /// </summary>
    /// <value>
    /// <see langword="true"/> if the menu item can be checked; otherwise, <see langword="false"/>.
    /// </value>
    bool IsCheckable
    {
        get;
        set;
    }
    #endregion

    #region IsChecked
    /// <summary>
    /// Gets or sets a value that indicates whether the menu item is checked.
    /// </summary>
    /// <value>
    /// <see langword="true"/> if the menu item is checked; otherwise, <see langword="false"/>.
    /// </value>
    bool IsChecked
    {
        get;
        set;
    }
    #endregion

    #region IsHorizontallyResizable
    /// <summary>
    /// Gets or sets a value that indicates whether the menu item can be resized horizontally.
    /// </summary>
    /// <value>
    /// <see langword="true"/> if the menu item can be resized horizontally; otherwise, <see langword="false"/>.
    /// </value>
    bool IsHorizontallyResizable
    {
        get;
        set;
    }
    #endregion

    #region IsVerticallyResizable
    /// <summary>
    /// Gets or sets a value that indicates whether the menu item can be resized vertically.
    /// </summary>
    /// <value>
    /// <see langword="true"/> if the menu item can be resized vertically; otherwise, <see langword="false"/>.
    /// </value>
    bool IsVerticallyResizable
    {
        get;
        set;
    }
    #endregion

    #region Items
    /// <summary>
    /// Gets the child menu items for the menu item.
    /// </summary>
    /// <value>
    /// A <see cref="SelectableObservableCollection{IMenuItem}"/> collection that contains the child menu items for the menu item.
    /// </value>
    SelectableObservableCollection<IMenuItem> Items
    {
        get;
    }
    #endregion

    #region KeyTip
    /// <summary>
    /// Gets or sets the text to use for the menu item key tip.
    /// </summary>
    /// <value>
    /// The text to use for the menu item key tip.
    /// </value>
    string KeyTip
    {
        get;
        set;
    }
    #endregion

    #region ToolTipDescription
    /// <summary>
    /// Gets or sets the description for the menu item tooltip.
    /// </summary>
    /// <value>
    /// The description for the menu item tooltip.
    /// </value>
    string ToolTipDescription
    {
        get;
        set;
    }
    #endregion

    #region ToolTipFooterDescription
    /// <summary>
    /// Gets or sets the description for the menu item tooltip footer.
    /// </summary>
    /// <value>
    /// The description for the menu item tooltip footer.
    /// </value>
    string ToolTipFooterDescription
    {
        get;
        set;
    }
    #endregion

    #region ToolTipFooterImage
    /// <summary>
    /// Gets or sets the image for the menu item tooltip footer.
    /// </summary>
    /// <value>
    /// The <see cref="ImageSource"/> for the menu item tooltip footer.
    /// </value>
    ImageSource ToolTipFooterImage
    {
        get;
        set;
    }
    #endregion

    #region ToolTipFooterTitle
    /// <summary>
    /// Gets or sets the title for the menu item tooltip footer.
    /// </summary>
    /// <value>
    /// The title for the menu item tooltip footer.
    /// </value>
    string ToolTipFooterTitle
    {
        get;
        set;
    }
    #endregion

    #region ToolTipImage
    /// <summary>
    /// Gets or sets the image for the menu item tooltip.
    /// </summary>
    /// <value>
    /// The <see cref="ImageSource"/> for the menu item tooltip.
    /// </value>
    ImageSource ToolTipImage
    {
        get;
        set;
    }
    #endregion

    #region ToolTipTitle
    /// <summary>
    /// Gets or sets the title for the menu item tooltip.
    /// </summary>
    /// <value>
    /// The title for the menu item tooltip.
    /// </value>
    string ToolTipTitle
    {
        get;
        set;
    }
    #endregion
}

public interface INavigationTab : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
    #region Groups
    /// <summary>
    /// Gets the groups for the navigation tab.
    /// </summary>
    /// <value>
    /// A <see cref="SelectableObservableCollection{INavigationTabGroup}"/> collection that contains 
    /// the navigation groups for the navigation tab.
    /// </value>
    SelectableObservableCollection<INavigationTabGroup> Groups
    {
        get;
    }
    #endregion

    #region Header
    /// <summary>
    /// Gets or sets the item that labels the navigation tab.
    /// </summary>
    /// <value>
    /// The item that labels the navigation tab.
    /// </value>
    object Header
    {
        get;
        set;
    }
    #endregion
}

public interface INavigationTabGroup : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
    #region Header
    /// <summary>
    /// Gets or sets the item that labels the navigation tab group.
    /// </summary>
    /// <value>
    /// The item that labels the navigation tab group.
    /// </value>
    object Header
    {
        get;
        set;
    }
    #endregion

    #region Items
    /// <summary>
    /// Gets the items for the navigation tab group.
    /// </summary>
    /// <value>
    /// A <see cref="SelectableObservableCollection{INavigationTabGroupItem}"/> collection that contains 
    /// the navigation items for the navigation tab group.
    /// </value>
    SelectableObservableCollection<INavigationTabGroupItem> Items
    {
        get;
    }
    #endregion
}

public interface INavigationTabGroupItem : ICloneable, INotifyPropertyChanged, INotifyPropertyChanging
{
    #region Command
    /// <summary>
    /// Gets or sets the command associated with the navigation tab group item.
    /// </summary>
    /// <value>
    /// The <see cref="ISurrogateCommand"/> associated with the navigation tab group item.
    /// </value>
    ISurrogateCommand Command
    {
        get;
        set;
    }
    #endregion

    #region CommandParameter
    /// <summary>
    /// Gets or sets the parameter to pass to the command associated with the navigation tab group item.
    /// </summary>
    /// <value>
    /// The parameter to pass to the <see cref="Command"/> associated with the navigation tab group item.
    /// </value>
    object CommandParameter
    {
        get;
        set;
    }
    #endregion

    #region Label
    /// <summary>
    /// Gets or sets the item that labels the navigation tab group item.
    /// </summary>
    /// <value>
    /// The item that labels the navigation tab group item.
    /// </value>
    object Label
    {
        get;
        set;
    }
    #endregion

    #region LargeImage
    /// <summary>
    /// Gets or sets the large image that is displayed by the navigation tab group item.
    /// </summary>
    /// <value>
    /// The <see cref="ImageSource"/> that represents the large image that is displayed 
    /// by the navigation tab group item.
    /// </value>
    ImageSource LargeImage
    {
        get;
        set;
    }
    #endregion

    #region SmallImage
    /// <summary>
    /// Gets or sets the small image that is displayed by the navigation tab group item.
    /// </summary>
    /// <value>
    /// The <see cref="ImageSource"/> that represents the small image that is displayed 
    /// by the navigation tab group item.
    /// </value>
    ImageSource SmallImage
    {
        get;
        set;
    }
    #endregion
}

以下是填充其Tabs集合的视图模型示例:

private void AddTabs()
{
    INavigationTab homeTab              = new NavigationTab(Properties.Resources.Shell_Tab_Home_Header);

    INavigationTabGroup generalGroup    = new NavigationTabGroup(Properties.Resources.Shell_TabGroup_General_Header);
    generalGroup.Items.Add(
        new NavigationTabGroupItem
        {
            Label               = Properties.Resources.Shell_StartPage_Header,
            LargeImage          = GetImage("/MyApp;component/Resources/Images/Home.png"),
            CommandParameter    = this,
            Command             = this.DisplayStartPage
        }
    );
    generalGroup.Items.Add(
        new NavigationTabGroupItem
        {
            Label       = Properties.Resources.Shell_Settings_Header,
            SmallImage  = GetImage("/MyApp;component/Resources/Icons/Settings.png")
        }
    );
    generalGroup.Items.Add(
        new NavigationTabGroupItem
        {
            Label       = Properties.Resources.Shell_UserInformation_Header,
            SmallImage  = GetImage("/MyApp;component/Resources/Icons/UserInformation.png")
        }
    );
    generalGroup.Items.Add(
        new NavigationTabGroupItem
        {
            Label       = Properties.Resources.Shell_About_Header,
            SmallImage  = GetImage("/MyApp;component/Resources/Icons/About.png"),
            Command     = this.AboutApplication
        }
    );

    homeTab.Groups.Add(generalGroup);

    this.Tabs.Add(homeTab);
}

另外,我最初在绑定图像源方面遇到了一些问题,但是使用Freeze找到了一个解决方案。这是一个例子:

// Build navigation tab
this.Tab    = new NavigationTab(Properties.Resources.Module_Tab_Header);

var administrationImage = GetImage("/MyApp;component/Resources/Images/Administration.png");
administrationImage.Freeze();

INavigationTabGroup administrationGroup = new NavigationTabGroup(Properties.Resources.Module_TabGroup_Administration_Header);
administrationGroup.Items.Add(
    new NavigationTabGroupItem
    {
        Label               = Properties.Resources.Module_StartPage_Header,
        LargeImage          = administrationImage
    }
);

/// <summary>
/// Gets an image resource in the assembly for the specified path.
/// </summary>
/// <param name="path">The relative path to the image resource.</param>
/// <returns>
/// The <see cref="System.Windows.Media.ImageSource"/> located at the specified <paramref name="path"/>.
/// </returns>
/// <example>
/// Path: <i>/MyAssembly;component/Resources/Icons/MyIcon.png</i>
/// </example>
protected static System.Windows.Media.ImageSource GetImage(string path)
{
    return new System.Windows.Media.Imaging.BitmapImage(
            new Uri(String.Format(null, "pack://application:,,,{0}", path))
    );
}

希望这可以帮助您解决绑定问题。