使用 Prism 激活/停用工具栏按钮

发布于 2024-10-28 01:47:32 字数 1560 浏览 1 评论 0原文

我正在学习 Prism 框架,并且已经取得了一些进展。但我想知道如何创建工具栏(和上下文菜单),其中每个模块都可以注册自己的按钮。

对于此示例,我希望所有按钮都驻留在位于我的 Shell 中的同一个 ToolBar 控件中。 ToolBars ItemsSource 绑定到视图模型中 ObservableCollection 类型的 ToolBarItems 属性。可以使用 ToolBarRegistry 服务将元素添加到此集合中。这是 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; }
    }
}

请注意,如果这是正确的解决方案,FrameworkElement 类型的集合将被重构为更具体的类型。

我的 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);
}

我从我的 OrderModule 调用此方法,并且按钮正确显示。到目前为止,一切都很好。

问题是我如何控制何时再次删除这些按钮。如果我导航到另一个模块中的视图(有时是同一模块中的另一个视图),我希望再次隐藏这些特定于模块的按钮。

您对如何执行此操作有什么建议吗?我是否以错误的方式处理这个问题,或者我可以修改我已有的内容吗?你是如何解决这个问题的?

I’m in the process of learning the Prism framework and I’ve come along way already. 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. The ToolBars ItemsSource binds to a ToolBarItems property of type ObservableCollection<FrameworkElement> in the view model. Elements can be added to this collection using a ToolBarRegistry service. This is the 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.

My ToolBarRegistry has a method to register image buttons:

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. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

⒈起吃苦の倖褔 2024-11-04 01:47:32

我不会在 ObservableCollection 中插入 Button 实例。考虑一下这种方法:

为工具栏按钮创建 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; }
}

然后当然将 ToolBarItems 的类型更改为这些按钮的集合。

ShellView 中,为 ToolBarButtonViewModel 添加一个 DataTemplate,并将工具栏控件的 ItemsSource 绑定到集合例如:

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

您现在可以使用 BooleanToVisibilityConverter 来解决您眼前的问题。

作为额外的好处,您还可以:

  • 完全从 XAML 更改工具栏按钮的视觉外观
  • 将工具栏按钮的可视化树的任何属性绑定到 ToolBarButtonViewModel 上的相应属性

更新启用

/禁用按钮取决于您的应用程序的具体情况。有很多选项 - 这里有一些(保留 此图表):

I would not insert Button instances in the ObservableCollection. Think about this approach instead:

Create ViewModel for the toolbar buttons

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.

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:

<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.

As an added bonus, you can also:

  • Change the visual appearance of the toolbar buttons entirely from XAML
  • Bind any property of the visual tree for a toolbar button to corresponding properties on the 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
  • Attach handlers to the events of IRegionNavigationService of the region(s) of interest and have the handlers enable or disable buttons
  • Route all navigation through your own code (CustomNavigationService) and decide what to do inside it
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文