简体   繁体   English

使用Prism激活/取消激活工具栏按钮

[英]Activation/deactivation of toolbar buttons using Prism

I'm in the process of learning the Prism framework and I've come along way already. 我正在学习Prism框架,我已经顺其自然了。 But I was wondering about how to create toolbars (and context menus) where each module can register their own buttons. 但我想知道如何创建工具栏(和上下文菜单),每个模块可以注册自己的按钮。

For this example I want all buttons to reside in the same ToolBar control which is located in my Shell. 对于此示例,我希望所有按钮都驻留在我的Shell中的同一ToolBar控件中。 The ToolBars ItemsSource binds to a ToolBarItems property of type ObservableCollection<FrameworkElement> in the view model. ToolBars ItemsSource绑定到视图模型中ObservableCollection<FrameworkElement>类型的ToolBarItems属性。 Elements can be added to this collection using a ToolBarRegistry service. 可以使用ToolBarRegistry服务将元素添加到此集合中。 This is the ViewModel: 这是ViewModel:

public class ShellViewModel
{
    private IToolBarRegistry _toolBarRegistry;
    private ObservableCollection<FrameworkElement> _toolBarItems;

    public ShellViewModel()
    {
        _toolBarItems = new ObservableCollection<FrameworkElement>();
        _toolBarRegistry = new ToolBarRegistry(this);
    }

    public ObservableCollection<FrameworkElement> ToolBarItems
    {
        get { return _toolBarItems; }
    }
}

Note that the collection of type FrameworkElement will be refactored to be of a more concrete type if this turns out to be the correct solution. 请注意,如果事实证明这是一个更正确的解决方案,那么FrameworkElement类型的集合将被重构为更具体的类型。

My ToolBarRegistry has a method to register image buttons: 我的ToolBarRegistry有一个注册图像按钮的方法:

public void RegisterImageButton(string imageSource, ICommand command)
{
    var icon = new BitmapImage(new Uri(imageSource));

    var img = new Image();
    img.Source = icon;
    img.Width = 16;

    var btn = new Button();
    btn.Content = img;
    btn.Command = command;

    _shellViewModel.ToolBarItems.Add(btn);
}

I call this method from my OrderModule and the buttons show up correctly. 我从OrderModule调用此方法,按钮显示正确。 So far so good. 到现在为止还挺好。

The problem is how I can control when these buttons should be removed again. 问题是如何控制何时应该再次删除这些按钮。 If I navigate to a view in another module (and sometimes another view in the same module), I want these module-specific buttons to be hidden again. 如果我导航到另一个模块中的视图(有时是同一模块中的另一个视图),我希望再次隐藏这些特定于模块的按钮。

Do you have any suggestions on how to do this? 你对如何做这个有什么建议吗? Am I approaching this problem the wrong way, or can I modify what I already have? 我是以错误的方式处理这个问题,还是可以修改我已有的问题? How did you solve this problem? 你是怎么解决这个问题的?

I would not insert Button instances in the ObservableCollection . 我不会在ObservableCollection插入Button实例。 Think about this approach instead: 改为考虑这种方法:

Create ViewModel for the toolbar buttons 为工具栏按钮创建ViewModel

class ToolBarButtonViewModel : INotifyPropertyChanged
{
    // INotifyPropertyChanged implementation to be provided by you

    public string ImageSource { get; set; }
    public ICommand Command { get; set; }
    public bool IsVisible { get; set; }
}

Then of course change the type of ToolBarItems to a collection of these. 然后当然将ToolBarItems的类型更改为这些的集合。

In your ShellView , add a DataTemplate for ToolBarButtonViewModel and bind the ItemsSource of whatever your toolbar control is to the collection of ViewModels, for example: ShellView ,为ToolBarButtonViewModel添加DataTemplate ,并将任何工具栏控件的ItemsSource绑定到ViewModel集合,例如:

<DataTemplate>
    <Button Command="{Binding Command}">
        <Button.Content>
            <Image Source="{Binding ImageSource}" />
        </Button.Content>
    </Button>
</DataTemplate>

You can now bind Button.Visibility to IsVisible with a BooleanToVisibilityConverter to solve your immediate problem. 现在,您可以使用BooleanToVisibilityConverterButton.Visibility绑定到IsVisible ,以解决您的紧急问题。

As an added bonus, you can also: 作为额外的奖励,您还可以:

  • Change the visual appearance of the toolbar buttons entirely from XAML 完全从XAML更改工具栏按钮的视觉外观
  • Bind any property of the visual tree for a toolbar button to corresponding properties on the ToolBarButtonViewModel 将工具栏按钮的任何属性绑定到ToolBarButtonViewModel上的相应属性

Update 更新

The mechanism for enabling/disabling buttons depends on specifics of your application. 启用/禁用按钮的机制取决于应用程序的细节。 There are many options -- here are a few (keep this chart in mind while reading): 有很多选择 - 这里有一些(在阅读时记住这个图表 ):

  • Implement INavigationAware in your Views or ViewModels and enable/disable buttons as required 在Views或ViewModels中实现INavigationAware ,并根据需要启用/禁用按钮
  • Attach handlers to the events of IRegionNavigationService of the region(s) of interest and have the handlers enable or disable buttons 将处理程序附加到感兴趣区域IRegionNavigationService事件,并让处理程序启用或禁用按钮
  • Route all navigation through your own code ( CustomNavigationService ) and decide what to do inside it 通过您自己的代码( CustomNavigationService )路由所有导航,并决定在其中执行的操作

Here is an article on that subject --it should help with your questions. 这是一篇关于该主题的文章 - 应该有助于解答您的问题。 It covers having modules load their own task buttons and Ribbon tabs. 它包括让模块加载自己的任务按钮和功能区选项卡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM