MVVM属性不会更新

时间:2015-03-25 09:44:13

标签: c# wpf 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());
                }
            });
        }
    }
}

我的ViewModel看起来像

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>

为什么不更新?

3 个答案:

答案 0 :(得分:0)

您未在SomeTest属性上提升RaisePropertyChanged("SomeTest")。它为什么会起作用? :)

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我建议您在event课程中实施CentralModel,并在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的事件处理程序委托和{{1}}属性得到更新。

修改

此外,this answer提供的fix-likes-coding是正确的:您需要绑定到视图中的正确属性。