MVVM 属性不会更新



我在属性更新方面遇到奇怪的问题

我的模型看起来像

using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using TestSome.DataType;
using TestSome.MessageInfrastructure;
using TestSome.WorkingWithNode;
namespace TestSome.Model
{
    class CentralModel
    {
        private BalanceTest someTest;
        public BalanceTest SomeTest
        {
            get { return someTest; }
            set { someTest = value; }
        }
        public void ListenBalance()
        {
            SocketHandler.Socket.Handle.Add("balance", (m) =>
            {
                try
                {
                    BalanceTest bt = m.Message.Json.GetFirstArgAs<BalanceTest>();
                    SomeTest = bt;
                    Messenger.Default.Send(new BalanceCommunicator { TestBalance = bt }, "Token");
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show(ex.Message.ToString());
                }
            });
        }
    }
}

我的视图模型看起来像

public class BalanceViewModel : ViewModelBase
{
    private BalanceTest some;
    public BalanceTest Some
    {
        get { return some; }
        set { some = value; RaisePropertyChanged("Some"); }
    }
    private CentralModel CM;
    public BalanceViewModel()
        {
            try
            {
                CM = new CentralModel();
                CM.ListenBalance();
                Some = CM.SomeTest;
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message.ToString());
            }
        }

Xaml看起来像

<UserControl x:Class="TestSome.Views.BalanceView"
         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:Test="clr-namespace:TestSome.Model"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <Test:CentralModel x:Key="CentralMode"></Test:CentralModel>
</UserControl.Resources>
<Expander ExpandDirection="Right">
<StackPanel Orientation="Horizontal">
        <Label Content="{Binding SomeTest.Balance,Source={StaticResource CentralMode},Mode=TwoWay}"></Label>
</StackPanel>
</Expander>

为什么它不更新?

我建议您在CentralModel类中实现一个event,并在BalanceViewModel中实现一个处理程序,以便向上传达新数据。

在 CentralModel 类中:

/// <summary>
/// Raised when a new balance is received.
/// </summary>
public event EventHandler<EventArgs> NewBalanceEvent;
public void ListenBalance()
{
    SocketHandler.Socket.Handle.Add("balance", (m) =>
    {
        try
        {
            BalanceTest bt = m.Message.Json.GetFirstArgAs<BalanceTest>();
            SomeTest = bt;
            Messenger.Default.Send(new BalanceCommunicator { TestBalance = bt }, "Token");
            // Raise the event
            EventHandler<EventArgs> RaiseNewBalanceEvent = NewBalanceEvent;
            if (null != RaiseNewBalanceEvent)
            {
                RaiseNewBalanceEvent(this, EventArgs.Empty);
            }
        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show(ex.Message.ToString());
        }
    });
}

在你的 BalanceViewModel 类中,钩住事件:

private void NewBalanceEventHandler(Object sender, EventArgs args)
{
    // This will trigger the property changed event.
    Some = CM.SomeTest;
}
public BalanceViewModel()
{
    try
    {
        CM = new CentralModel();
        CM.ListenBalance();
        Some = CM.SomeTest;
        // Attach to the NewBalance event
        // Note: you should detatch it again (with -=) when you've finished with it.
        CM.NewBalanceEvent += NewBalanceEventHandler;
    }
    catch (Exception ex)
    {
        System.Windows.MessageBox.Show(ex.Message.ToString());
    }
}

现在,每当调用SocketHandler.Socket.Handle.Add中的 Lambda 时,CentralModel都会引发NewBalanceEvent,而又(通过框架(调用BalanceViewModel的事件处理程序委托,并且 Some 属性得到更新。

编辑

此外,由类似修复编码提供的这个答案是正确的:您需要绑定到视图中的正确属性。

您不会在 SomeTest 属性上引发RaisePropertyChanged("SomeTest")。为什么会起作用?:)

您需要绑定到Some 的 BalanceViewModel 而不是 CentralModel

<Label Content="{Binding Path=Some.Balance,Mode=TwoWay}"></Label>

最新更新