在WPF / MVVM / Prism中实现菜单按钮

时间:2013-10-28 11:07:45

标签: wpf mvvm prism datatemplate

我在WPF应用程序的左上角有一个Region,我希望它是我的全局按钮栏,用户可以在其中选择要查看的屏幕,然后相应的内容将显示在主区域中。这也是右上角的子导航区域,在该屏幕中有子菜单选项,例如,如果用户从主菜单中单击“维护”,子菜单将显示新建,更新,删除,编辑等选项。

我想要的是一种通过简单地指定文本按钮名称列表来创建自定义菜单栏的方法,以及用于在按钮单击时调用的操作的ICommand / Parameter对。执行此操作的自然方法是使用具有依赖项属性Title,Command和CommandParameter的MenuButtonViewModel类。 IsSelected还需要另外一个,因此用户可以通过一些直观的方式查看您当前所在的屏幕,因此它需要像切换按钮一样,但只能在一个按钮中选择一个按钮。时间。然后我可以有一个UserControl,其中条形图的内容绑定到ObservableCollection并使用数据模板来呈现按钮栏。

到目前为止,我已经尝试了几种方法,但无法找到一种方法,可以提供我想要的视觉行为。这些是我的要求

1)用于将背景更改为其他Brush OnMouseOver的按钮 2)当选择按钮时,将显示另一个画笔作为背景,直到选择组中的新按钮,如togglebutton IsSelected行为 3)一次只能选择组中的一个按钮

到目前为止,我尝试这样做的方法是

1)使用我自己的类扩展RadioButton,为命令和命令参数添加依赖项属性。将所有控件设置为具有相同的组ID。数据模板,用于覆盖单选按钮的显示,使其看起来像带有鼠标悬停和被选中触发器的可视按钮。

这项工作正常,除了一件事。选择组中的单选按钮后,无法取消选择单选按钮组中的所有选项。因此,如果您导航到“维护”,然后单击“国家/地区”的子菜单,则会显示国家/地区维护屏幕。然后,如果您转到应用程序的其他区域并从主菜单中选择“交易条目”,您将进入交易输入屏幕。如果然后单击“维护”,它将显示通用的“维护”内容并带回用于维护的子菜单控件,其中在单选按钮组中选择“国家/地区”,但这是不合需要的。当您导航回维护时,它应取消选择所有子菜单选项,显示通用维护登录页面内容,并在显示该屏幕内容之前让您选择子菜单选项。第一次加载维护时,没有选择任何内容,但是一旦选择了选项,则在重新加载维护屏幕时无法再选择任何内容。

2)然后我尝试扩展一个ListBox,使用水平堆栈面板为内容设置样式,每个listboxitem都是一个menubuttonViewModel。这允许我一次只选择一个选项,并在离开页面时清除选择。它还允许我在鼠标悬停在每个listboxitem上时更改背景。

我无法使用列表框的位置是IsSelected触发器的背景不同。在默认的ListBoxItem模板上似乎有一些触发器会覆盖你在CSS中指定的任何内容,所以无论我在listboxitem或menubuttonviewmodel样式上放置什么触发器,背景都不会改变。我想我需要重新定义listboxitem的数据和内容模板,但只有它适用于此列表框,所以它不能是对所有listboxitems的全局模板更改 - 因为我希望能够在应用程序的其他地方使用列表框没有继承这种行为。

任何人都可以对这两种方法提出自己的想法,以及如何解决我必须让其中一种方法以我想要的方式工作的问题,特别是如果你可以建议我如何覆盖内容/数据模板我的风格的listboxitems,所以他们不使用默认触发器,我可以让IsSelected触发器为我工作?

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您希望每次 导航时,从子菜单清除 RadioButtons 上的选项> 从另一个主菜单选项返回。

为了解决这个问题,您可以手动将 RadioButton的IsChecked 属性值设置为单选按钮 “取消选中” 即可。可能的解决方案如下:

如果您想在每次导航到主菜单的其他部分时清除子菜单中的任何选中选项,您可以先通知子菜单的ViewModel 通过从 SelectionChangedEventHandler MainMenu 按钮后使用 EventAggregator 发布事件> 主菜单ViewModel的方法

因此,已发布事件的子菜单EventHandler 会将每个 RadioButton的IsChecked 属性值更新为 false < / strong>,可以通过在视图上定义的每个 IsChecked 属性之间使用“双向”绑定来完成在 ViewModel 上实现布尔 “RadioButton1IsChecked” 属性。

我希望这对你有所帮助。