【问题标题】:Trouble with static fields when binding绑定时出现静态字段问题
【发布时间】:2016-05-05 14:09:00
【问题描述】:

我在 Model 类中有一个静态 bool 属性,我将它公开给两个不同的 ViewModel 类。其中一个 ViewModel 有一个 bool 属性链接到所述静态属性,并通过转换器绑定到按钮的 Visibility。然后可以在该 ViewModel 中将其设置为 true 或 false,并且按钮的可见性会相应更改。 (此 ViewModel 的实例通过按钮所在的 DataContext 在 View 的 XAML 中设置) 我希望能够从不同的视图中更改此按钮的可见性,并且我认为通过在我的单独视图的 ViewModel 中拥有一个也链接到我的原始模型中的静态布尔值的属性,我可以做到这一点,但它不是什么都不做。

这是我的代码:

主模型

public class MainModel
{
    static bool _ButtonIsVisible = true;

    public static bool ButtonIsVisible
    {
        get { return _ButtonIsVisible; }
        set { _ButtonIsVisible = value; }
    }
}

MainViewModel

class MainViewModel: ObserveableObject
{
    public bool ButtonIsVisible
    {
        get { return MainModel.ButtonIsVisible; }
        set
        {
            MainModel.ButtonIsVisible = value;
            RaisePropertyChanged("ButtonIsVisible");
        }
    }
}

主视图

<Window x:Class="MVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:MVVM"  
    mc:Ignorable="d"
    Title="MainWindow" Width="1920" Height="1080" WindowState="Maximized" WindowStyle="None">

    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>

    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
    </Window.Resources>

    <Button Visibility="{Binding ButtonIsVisible, Converter={StaticResource BoolToVisConverter}}" />
</Window>

来自 MainViewModel 的 ButtonIsVisible 在命令中更改,这可以按预期工作。这就是我的麻烦发生的地方。

另一个视图模型

class AnotherViewModel: ObserveableObject
{
    public bool ButtonIsVisible
    {
        get { return MainModel.ButtonIsVisible; }
        set
        {
            MainModel.ButtonIsVisible = value;
            RaisePropertyChanged("ButtonIsVisible");
        }
    }
}

AnotherViewModel 的一个实例是通过其相应视图的 DataContext 创建的,并且一个命令绑定到此视图中的一个按钮,在该按钮中我从 AnotherViewModel 更改 ButtonIsVisible 属性,此时我希望我的 MainView 中的按钮更改,看到两个 ViewModel 从我的 MainModel 中的静态属性获取和设置相关属性的值,但这不起作用。 谁能告诉我我做错了什么?

【问题讨论】:

  • 现在我不能告诉你为什么它不工作,但我真的用静态属性来做这件事听起来很糟糕。我宁愿将MainViewModel ButtonIsVisibleproperty 从AnotherViewModel 更改为MainViewModelinstance 在构造函数中发送到AnotherViewModel
  • 现在我想起来了,在AnotherViewModel 中你调用RaisePropertyChanged,但这会影响AnotherViewModel 的视图,而不是MainViewMainView 没有收到属性更改事件...
  • 我不得不承认,即使我自己也不喜欢使用静态属性来做到这一点。我可能会在以后找到更好的方法,但我现在就用这个​​来让球滚动起来。您的第二条评论是有道理的,但是有什么办法可以解决这个问题吗?我可以通知MainViewModel AnotherViewModel 中的更改吗?
  • @Howard_Schmidtt 在这里,更好的方法意味着实际可行的方法。您的方法根本不会,因为在一个视图模型中设置属性不会触发另一个视图模型中的 PropertyChanged 事件
  • 嗯,有几种方法可以做到这一点,从非常简单到非常复杂。例如,您可以使用 EventHandler 通知主视图它已更改。但我会采用我之前告诉过您的简单解决方案:将 MainViewModel 实例传递给 AnotherViewModel 并从那里更改属性。另外,这样你就可以摆脱那个丑陋的静态属性

标签: c# wpf mvvm binding static


【解决方案1】:

根据你的 cmets,你有这样的东西:

<ContentControl Content="{Binding ViewModel}" />

当你想展示它时,你正在这样做:

ViewModel = new AnotherViewModel();

那么您需要的 AnotherViewModel 是:

MainViewModel MVM;

public AnotherViewModel(MainViewModel _mvm)
{
     this.MVM=_mvm;
}

然后您必须将您的 AnotherVieModel 实例更改为:

ViewModel = new AnotherViewModel(this);

当你想改变按钮的可见性时,你只需要这样做:

this.MVM.ButtonIsVisible=true;

正如我告诉你的,这只是一种方法,但我认为它非常简单且不稳定。如果您有任何疑问,请随时提出。

【讨论】:

  • 我知道你来自哪里,它确实看起来相对简单直接,太棒了!不过,我确实有一个问题,当您说:“您必须将您的 AnotherViewModel 实例更改为:ViewModel = new AnotherViewModel(this);”时,这到底会去哪里?就目前而言,我的另一个视图模型的实例化是在它的相应视图的 xaml 中完成的。
  • 嗯,我总是在后面的代码中实例化 viemodel。我建议您将其从 xaml 中删除,并在 MainViewModel 中执行AnotherView w=new AnotherView(); w.DataContext=new AnotherViewModel(this); w.Show(); 之类的操作,但没有看到您的代码到底是怎样的,我无法再告诉您了:)
  • 当我切换视图时,我设法做到了SelectedViewModel = new AnotherViewModel(this);,但是当我尝试this.MVM.ButtonIsVisible = true; 时,我得到一个 NullReferenceException,告诉我 MVM 尚未设置为对象的实例,但是当我更改视图时,我可以看到它被设置为我的 MainViewModel,那么为什么它之后变为 null 超出了我的范围?顺便感谢您的帮助!我肯定在朝着正确的方向前进,我觉得我现在就快到了!
  • 没有看到你的代码我只能猜测。也许您仍在 xaml 中实例化视图模型?如果是这样,请将其删除
  • 单步执行代码我可以看到,当我切换视图时,我传入了我的MainViewModel,这很好,但是因为我在我的AnotherView xaml 它当然是空的!看起来我确实必须在我的视图的代码隐藏文件中实例化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 2014-04-21
  • 2011-03-07
  • 2016-02-16
  • 1970-01-01
相关资源
最近更新 更多