在模型中使用viewmodel属性并将模型中更改的相同属性通知给viewmodel以绑定到view

时间:2015-09-01 13:10:04

标签: wpf mvvm inotifypropertychanged

SingleMessage.xaml将viewmodel作为SingleMessageViewModel.cs,此viewmodel使用LogAcitvity类作为属性,并且viewmodel中定义的属性绑定到SingleMessage.xaml。 现在我想在SocketClient.cs(Model)中使用this(viewmodel)属性,并希望在viewmodel中通知属性更改以更新视图。

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {   
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

LogActivity类,其属性在viewmodel中使用

public class LogActivity : ViewModelBase
{      
    private string messageLog;
    public string MessageLog
    {
        get { return messageLog; }
        set
        {
            if (value != messageLog)
            {
                messageLog = value;
                NotifyPropertyChanged("MessageLog");
            }
        }
    } 
}   

这是我的viewmodel类

public class SingleMessageViewModel : ViewModelBase
{
    private LogActivity messagelog;

    public SingleMessageViewModel()
    {
        messagelog = new LogActivity();
    }   

    public LogActivity MessageLog
    {
        get { return messagelog; }
        set
        {
            if (value != messagelog)
            {
                messagelog = value;
                NotifyPropertyChanged("MessageLog");
            }
        }
    }  
 }

这是我的观点

<TextBox x:Name="TxtLog" Text="{Binding MessageLog.MessageLog, UpdateSourceTrigger=PropertyChanged}"  Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" />

现在我想在我的SocketClient.cs模型类的viewmodel中使用此MessageLog属性,并希望将其更改通知viewmodel。 这样更新就会发生。而且这个问题在异步方法调用中也有所改变,所以我想使用这个语法来更新viewmodel属性:

public class SocketClient : INotifyPropertyChanged
{
    App.Current.Dispatcher.BeginInvoke((Action)delegate
    {
       MessageLog.MessageLog += messageTimeStamp + " : <- "  + szData.Replace("\n\0", "") + "\n";
    });
}

那么,如何在模型中使用viewmodel propety并将其通知给viewmodel

public LogActivity MessageLog
{
    get { return messagelog; }
    set
    {
        if (value != messagelog)
        {
            messagelog = value;
            NotifyPropertyChanged("MessageLog");
        }
    }
}  

我的模特看起来像这样..

namespace PCSTESTGUI.Models
{   

public class SocketClient : INotifyPropertyChanged
{
    // Receive buffer.       
    byte[] dataBuffer = new byte[256];
    IAsyncResult result;
    public AsyncCallback pfnCallBack;
    public Socket clientSocket;
    private LogActivity messagelog;
    //private SingleMessageViewModel SingleMVM;
    int portNo;
    string ipAddress;
    string filePathName;
    string receivedResponse;
    string message = string.Empty;
    string connstring = ConfigurationManager.AppSettings["XmlConfigurationSetting"].ToString();
    string fileName = ConfigurationManager.AppSettings["XmlConfiguratonSettingFileName"].ToString();
    string messageTimeStamp = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString();

        public SocketClient()
        {
            messagelog = new LogActivity();
            SingleMessageViewModel SingleMVM = new SingleMessageViewModel(this);            
            //get the IPAddress and PortNo from save configuration setting
            filePathName = connstring + "\\" + fileName;
            try
            {
                if (File.Exists(filePathName))
                {
                    XDocument xdoc = XDocument.Load(filePathName);
                    var configsetting = from cs in xdoc.Descendants("ConfigurationSetting")
                                        select cs;
                    foreach (var config in configsetting)
                    {
                        ipAddress = config.Element("IPAddress").Value;
                        portNo = Convert.ToInt16(config.Element("PortNo").Value);
                    }
                    // check ipaddress and port no exists
                    if (ipAddress == "" || portNo == 0)
                    {
                        MessageBox.Show("IP Address and Port Number are required to connect to the Server\n", "Socket Connection : Missing", MessageBoxButton.OK, MessageBoxImage.Error);
                        FileLogger.Handle("Missing IP Address / Port Number in the configuration settings file");
                        MessageLog.MessageLog += messageTimeStamp + " : Missing IP Address / Port Number in the configuration settings file\n";
                        return;
                    }
                    //connect to the server
                    ConnectServer();
                }              
            }
            catch (Exception ex)
            {
                FileLogger.Handle(ex.Message);
                MessageLog.MessageLog += messageTimeStamp + " : " + ex.Message + "\n";

            }
        }
        public SingleMessageViewModel SingleMVM
        {
            get;
            set;
        }
        public LogActivity  MessageLog
        {
            get
            {
                return messagelog;
            }
            set
            {
                messagelog = value;
                this.SingleMVM.MessageLog = value;            
                NotifyPropertyChanged("MessageLog");              
            }
        }

        public void ConnectServer()
        { 
            try
            {   
                // Get the remote IP address
                IPAddress ip = IPAddress.Parse(ipAddress);
                int iPortNo = portNo;
                // Create the socket instance
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                FileLogger.Handle("StartConnect - Trying socket connection to PCS server '" + ip.ToString() + "' on Port " + iPortNo.ToString());
                MessageLog.MessageLog += messageTimeStamp + " : StartConnect - Trying socket connection to PCS server '" + ip.ToString() + "' on Port " + iPortNo.ToString() + "\n";

                // Create the end point 
                IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo);
                // Connect to the remote host
                clientSocket.Connect(ipEnd);
                if (clientSocket.Connected)
                {
                    FileLogger.Handle("ProcessConnect - Client socket connected to PCS server '" + ip.ToString() + "' on Port " + iPortNo.ToString());
                    MessageLog.MessageLog += messageTimeStamp + " : ProcessConnect - Client socket connected to PCS server '" + ip.ToString() + "' on Port " + iPortNo.ToString() + "\n";

                    //Wait for data asynchronously 
                    WaitForData();
                }
                else
                {
                    ConnectServer();
                }
            }
            catch (SocketException ex)
            {
                FileLogger.Handle(ex.Message);
                MessageLog.MessageLog += messageTimeStamp + " : " + ex.Message + "\n";
            }
        }

        public void SendMessage(string message)
        {
            try
            {                
                if (!clientSocket.Connected)
                    ConnectServer();

                if (message != "")
                {
                    this.message = message + "\r\n";
                    byte[] byteMessage = Encoding.ASCII.GetBytes(this.message);
                    //NetworkStream networkStream = new NetworkStream(clientSocket);
                    //StreamWriter streamWriter = new StreamWriter(networkStream);
                    //streamWriter.WriteLine(byteMessage);
                    //streamWriter.Flush();
                    if (clientSocket != null && clientSocket.Connected)
                    {
                        FileLogger.Handle("Pseudo Command message processing tasks started");
                        FileLogger.Handle(" -> " + message.ToUpper());
                        MessageLog.MessageLog += messageTimeStamp + " : Pseudo Command message processing tasks started\n";
                        MessageLog.MessageLog += messageTimeStamp + " : -> " + message.ToUpper() + "\n";
                        clientSocket.Send(byteMessage);
                    }
                    else
                    {
                        ConnectServer();
                        if (clientSocket.Connected)
                        {
                            FileLogger.Handle("Pseudo Command message processing tasks started");
                            FileLogger.Handle(" -> " + message.ToUpper());
                            MessageLog.MessageLog += messageTimeStamp + " : Pseudo Command message processing tasks started\n";
                            MessageLog.MessageLog += messageTimeStamp + " : -> " + message.ToUpper() + "\n";
                            clientSocket.Send(byteMessage);
                        }
                    }
                }              
            }
            catch (Exception ex)
            {
                FileLogger.Handle(ex.Message);
                MessageLog.MessageLog += messageTimeStamp + " : " + ex.Message + "\n";
            }
        }

        public void DissconnectServer()
        {   
            clientSocket.Close();
            clientSocket = null;
            FileLogger.Handle("CloseConnection - Closed socket connection to PCS server '" + ipAddress + "' on Port " + portNo.ToString());
            MessageLog.MessageLog += messageTimeStamp + " : ProcessConnect - Client socket connected to PCS server '" + ipAddress + "' on Port " + portNo.ToString() + "\n";
        }

        public class SocketPacket
        {
            public System.Net.Sockets.Socket thisSocket;
            public byte[] dataBuffer = new byte[1024];
        }

        public void WaitForData()
        {
            try
            {
                if (pfnCallBack == null)
                {
                    pfnCallBack = new AsyncCallback(OnDataReceived);
                }
                SocketPacket theSocPkt = new SocketPacket();
                theSocPkt.thisSocket = clientSocket;
                // Start listening to the data asynchronously
                result = clientSocket.BeginReceive(theSocPkt.dataBuffer, 0, theSocPkt.dataBuffer.Length,
                                                      SocketFlags.None, pfnCallBack, theSocPkt);

                if (result.IsCompleted == false)
                {
                    Console.Write(".");
                }

            }
            catch (SocketException se)
            {
                FileLogger.Handle(se.Message);
                MessageLog.MessageLog += messageTimeStamp + " : " + se.Message + "\n";
            }
        }

        public void OnDataReceived(IAsyncResult asyn)
        {
            try
            {               
                SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
                int iRx = theSockId.thisSocket.EndReceive(asyn);
                char[] chars = new char[iRx + 1];
                System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
                int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
                System.String szData = new System.String(chars);
                receivedResponse = receivedResponse + szData + "\n";
                if (szData.ToString() != "\0" || szData.ToString() != "")
                {
                    FileLogger.Handle(" <- " + szData.Replace("\n\0", ""));

                    App.Current.Dispatcher.BeginInvoke((Action)delegate
                    {
                        MessageLog.MessageLog += messageTimeStamp + " : <- " + szData.Replace("\n\0", "") + "\n";
                        if (SingleMVM == null)
                            SingleMVM = new SingleMessageViewModel(this);
                        //this.SingleMVM.MessageLog.MessageLog += this.MessageLog.MessageLog;
                        this.SingleMVM.updateMesssage(szData.Replace("\n\0", ""));
                    });

                } 

                WaitForData();
            }
            catch (ObjectDisposedException ex)
            {                
                FileLogger.Handle(ex.Message);
                MessageLog.MessageLog += messageTimeStamp + " : " + ex.Message + "\n";               
            }
            catch (SocketException se)
            {
                FileLogger.Handle(se.Message);
                MessageLog.MessageLog += messageTimeStamp + " : " + se.Message + "\n";               
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

在OnDataReceived功能中,从服务器接收数据,需要更新数据以通过viewmodel属性MessageLog进行查看。 由于PropertyChanged为null,INofication不会引发事件。 但我正在贬值价值。

在viewmodel中读取此值并且它也通知属性调用,但属性更改为null,因此不会引发事件。

public void updateMesssage(string message)
{            
    App.Current.Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new Action(() =>
    {
        this.MessageLog.MessageLog += messageTimeStamp + " : <- " + message + "\n";
    }));
}

0 个答案:

没有答案