WPF导航和旋转背景

时间:2014-06-14 14:46:12

标签: c# wpf mvvm

我正在处理一个应用程序,而且我正在使用MVVM方法 基本上,目前有两个Page和一个MainWindow 我使用Frame内的MainWindow在页面之间切换。

在主窗口中,有2个基本上是全局的按钮,应该显示在所有页面中; x(退出)和设置 这基本上就是我的贝壳'因为我决定不使用窗口边框。

问题是我希望每个页面都有不同的背景,这就是它变得复杂的地方:
- 设置页面:灰色背景。
- 主页面:根据属性改变的旋转背景颜色。

事情是在主窗口中设置背景,因为它也应该应用于全局区域(顶部,出口和设置按钮所在的位置)。

我首先将背景(在MainWindow中)设置为绑定到表示当前页面的属性(然后在转换器的帮助下将值转换为颜色十六进制代码)。

总而言之,这会导致在更改页面时背景发生变化,而在MainPage内的属性发生变化时则不会。我可以清楚地理解为什么,但我不知道如何解决它。

到目前为止我提出的可能的解决方案:

  • MainWindow中更改属性时,以某种方式导致MainPage中的绑定更新/刷新。
  • 从每个页面内部手动更改背景。 (虽然它没有否定mvvm的想法吗?)
  • 将背景移动到每个页面并从那里进行设置,同时在页面顶部设置全局按钮(如果控件最终重叠,这可能是件坏事。)

如果是这样,那么这个问题的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:2)

如果您还没有,我建议您通过NuGet安装一些软件包,以使MVVM样式开发更加愉快。我个人更喜欢MVVMLight,这很好,很轻,但它也包含很多有用的功能。

要在ViewModels之间进行通信,您(至少)有两种可能的方法。

1)ViewModelLocator(不推荐)

ViewModelLocator是保存所有视图模型引用的中心位置。您可以添加一个属性,然后由所有视图模型使用该属性来获取/设置背景。

....
x:Name="Main"
DataContext="{Binding Source={StaticResource Locator}, Path=MainVM}">
....
<Grid Background="{Binding Background, Converter={StaticResource StringBrushConverter}}">
...

2)Messenger(推荐)

当您的viewmodel(s)或方法中的属性发生更改时,您可以发送一条消息,表明您的MainViewModel已注册为要侦听。发送消息就像......一样简单。

Messenger.Default.Send(new UpdateBackgroundMessage(new SolidColorBrush(Colors.Blue)));

您将在MainViewModel的构造函数中注册此消息:

Messenger.Default.Register<UpdateBackgroundMessage>(this, message =>
    {
        Background = message.Brush;
    });

实际邮件类别为:

public class UpdateBackgroundMessage : MessageBase
{
    public UpdateBackgroundMessage(Brush brush)
    {
        Brush = brush;
    }
    public Brush Brush { get; set; }
}

我知道我在这里简化了一些事情,但我希望你能有这个想法。 即使您决定不使用MVVMLight ,这两种方法都是有效的。

修改

这是带有示例https://github.com/mikkoviitala/cross-viewmodel-communication

的Git仓库

imgur

答案 1 :(得分:1)

我认为您应该使用Application Properties来存储背景。这有很多好处:

1)全球可用 2)易于记忆或存储用户偏好 3)为每个用户自动维护单独的配置文件,因为它将值存储在用户的AppData文件夹中。

您可以使用Messenger通知后台属性已更改,以便主窗口或shell可以提取新的背景值并更新它。