如果我从其他视图模型设置其值,为什么绑定到标签的一个字符串的propertyChange不会上升

时间:2017-10-26 23:25:03

标签: c# wpf mvvm

我有一个WPF应用程序,在视图1中有两个视图和两个模型视图,有一个Button和一个标签:

</WrapPanel>
<WrapPanel Orientation="Horizontal">
    <Button Command="{Binding InitServerCommand}" Content="Connect to Server" Margin="10 10 0 0"/>
</WrapPanel>
<WrapPanel Orientation="Horizontal">
    <Label Content="Info: " Style="{StaticResource myLabelStyle}"/>
<Label x:Name="lblInfoView" Content="{Binding Path=LblInfo, Mode=TwoWay}" Style="{StaticResource myLabelStyle}"/>
</WrapPanel>

在视图模型1中,我以这种方式声明了字段lblInfo:

     public class ViewModel1: BaseViewModel
        {
            public static string _lblInfo;
            public string LblInfo
            {
                get { return _lblInfo; }
                set
                {
                    if (_lblInfo != value)
                        _lblInfo = value;
                    OnPropertyChanged("LblInfo");
                }
            }
    }

此外,我有一个扩展INotifyPropertyChaged的基础模型:

     public abstract class BaseViewModel : INotifyPropertyChanged
        {

            public event PropertyChangedEventHandler PropertyChanged;

            protected BaseViewModel()
            {

            }

            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

我有一个函数可以进行somenthing并刷新LblInfo的值,它会自动映射到View 1中的Label上。

    public void send(string str)
            {
                try
                {
                    //Do somenthing
                    LblInfo = "Connect";
                }
                catch (Exception ex)
                {
                    LblInfo = "Error..... " + ex.StackTrace;
                }
            }

问题是:

如果在视图模型1中调用send(),程序会自动执行setter并在调用时

OnPropertyChanged("LblInfo"); 

propertyChanged与null不同,它会调用

Invoke(this, new PropertyChangedEventArgs(propertyName));

View 1成功更新了Label内容。

但是如果你从另一个模型View 2中调用该方法

public class ViewModel2: BaseViewModel
  {
          public ViewModel1 ConfigureParametersVM
    {
        get { return GetValue<ViewModel1>(); }
        set { SetValue(value); }
    }
        //Constructor
          public ViewModel2()
    {
        ConfigureParametersVM = new ViewModel1();
        //Execute the send method from View Model 1
        ConfigureParametersVM.send("update_mroi");
    }

}

它运行send方法,setter更新_lblInfo的值,但是当它调用OnPropertyChanged()时,propertyChanged等于null并且它不会更新View1中的Label。

我做错了什么?

其他信息

现在,我在ViewModel1或ViewModel2上没有提到DataContext,你能告诉我我该怎么办? View1(xaml)和(.xaml.cs)中的代码是:.xaml

<UserControl x:Class="Namespace1.Views.View1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Namespace1.Views"
             xmlns:GuiControlLibrary="clr-namespace:GuiControlLibrary;assembly=GuiControlLibrary"
             mc:Ignorable="d" 
             d:DesignHeight="768" d:DesignWidth="1024">
    <Grid>
             //Somethin else        
            <Grid>
                </StackPanel>
                <StackPanel Orientation="Vertical" Grid.Column="1">
                    <!--Code for TCP/IP Parameters-->
                     //More code not showed here
                    <WrapPanel Orientation="Horizontal">
            //This is the commad from Icommand that starts de method send()
                        <Button Command="{Binding InitServerCommand}" Content="Connect to Server" Margin="10 10 0 0"/>
                    </WrapPanel>
                    <WrapPanel Orientation="Horizontal">
            //Static label
                        <Label Content="Info: " Style="{StaticResource myLabelStyle}"/>
            //Binded label
                        <Label x:Name="lblInfoView" Content="{Binding Path=LblInfo, Mode=TwoWay}" Style="{StaticResource myLabelStyle}"/>
                    </WrapPanel>
                </StackPanel>
            </Grid>
    </Grid>
</UserControl>

.xaml.cs是:

using System.Windows.Controls;
namespace Namespace1.Views
{
    /// <summary>
    /// Interaction logic for View1.xaml
    /// </summary>
    public partial class View1 : UserControl
    {
        public View1()
        {
            InitializeComponent();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

根据您问题中的代码:

public ViewModel2()
{
    ConfigureParametersVM = new ViewModel1();
    //Execute the send method from View Model 1
    ConfigureParametersVM.send("update_mroi");
}

ConfigureParametersVM(ViewModel1)未分配为视图的DataContext。分配完成后,View将在ViewModel上注册PropertyChanged个事件。

答案 1 :(得分:0)

public static string _lblInfo;

这是错误的。它应该是:

private string _lblInfo;

这不会解决你的问题,但它会提供一个很好的暗示,为什么它不起作用。因为您从未调用视图模型实例的send方法。您创建了新的。这就像拥有第二个int并想知道为什么第一个int在设置第二个{ if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this } 时不会改变。因为它们是不同的实例。

您的ViewModel需要一种相互了解的方式,如果没有更多代码,我无法告诉您哪种方式最好。但是您需要连接现有两个实例,而不是创建新实例。