gpt4 book ai didi

c# - 模型更改后如何更新 View ?

转载 作者:行者123 更新时间:2023-12-03 10:36:35 25 4
gpt4 key购买 nike

假设我有一个 Logger类,一个LoggerViewModel类和 MainWindowTextBox . Logger class 是一个线程安全的单例,所以我在应用程序域中只有它的一个实例。

public sealed class Logger : INotifyPropertyChanged
{
private static readonly Logger _Instance = new Logger();

private static readonly object _SyncLock = new object();
private static List<LogEntry> _Data = new List<LogEntry>();

/// <summary>
///
/// </summary>
private Logger() { ; }

/// <summary>
///
/// </summary>
public static Logger Instance
{
get { return _Instance; }
}

/// <summary>
///
/// </summary>
/// <param name="entry"></param>
public void Write(LogEntry entry)
{
lock (_SyncLock)
{
_Data.Add(entry);
}
this.RaiseNotifyPropertyChanged("Entries");
}

/// <summary>
///
/// </summary>
/// <param name="component"></param>
/// <param name="message"></param>
public void Write(string component, string message)
{
LogEntry entry = LogEntry.Create(component, message);
Write(entry);
}

/// <summary>
///
/// </summary>
public IList<LogEntry> Entries
{
get
{
lock (_SyncLock)
{
return new ReadOnlyCollection<LogEntry>(_Data);
}
}
}

/// <summary>
///
/// </summary>
/// <param name="property"></param>
private void RaiseNotifyPropertyChanged(string property)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(property));
}
}

/// <summary>
///
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
}
Logger唯一实例在应用程序运行时由更多线程更新,因此我将更新 TextBoxMainWindow每当模型(即 Logger 单例类)更改时。

如何连接它们之间的模型和 View 模型?我强调Model只被几个应用线程改变,所以从UI的角度来看它是只读的。

我提供了 LoggerText LoggerViewModel 内的属性(property)上课,自以为下面的工作机制。
1. 当模型( Logger 实例)发生变化时,它会通知 ViewModel。
2. ViewModel 接收到 Model 的通知并创建一个新的 string包含来自记录器的所有消息。
3. ViewModel 通知 View。
public class LoggerViewModel : INotifyPropertyChanged
{
Logger _LoggerModel;

/// <summary>
///
/// </summary>
public LoggerViewModel()
{
_LoggerModel = Logger.Instance;
}

/// <summary>
///
/// </summary>
public string LoggerText
{
get
{
string text = "";
List<LogEntry> entries = new List<LogEntry>(_LoggerModel.Entries);
foreach (LogEntry entry in entries)
{
text += entry.ToString();
text += "\n";
}
return text;
}
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)
{
// take a copy to prevent thread issues
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

ViewModel如何拦截Model发送的通知?

最佳答案

首先,我不喜欢您使用单例。使用单例模式时,您在测试或重用 View Controller 时会感到很困难。我会改为注入(inject) Logger依赖于您的 LoggerViewModel类(class)。

除了解决问题的一种方法是为 PropertyChanged 注册一个处理程序。您的 Logger 上的事件并在 Entries 的事件触发时构建文本属性(property)。

LoggerViewModel然后,您将添加一个属性处理程序并更新 LoggerText属性(property)根据需要。

public LoggerViewModel(Logger loggerModel /* Dependency injection*/)
{
_LoggerModel = loggerModel;
_LoggerModel.PropertyChanged += this.LoggerModel_PropertyChanged;
}

private void LoggerModel_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
if (args.PropertyName == "Entries")
{
StringBuilder text = new StringBuilder(); // Use StringBuilder for performance
List<LogEntry> entries = new List<LogEntry>(_LoggerModel.Entries);
foreach (LogEntry entry in entries)
{
text.AppendLine(entry.ToString());
}
this.LoggerText = text.ToString();
}
}

private string _loggerText;
public string LoggerText
{
set
{
_loggerText = value;
RaisePropertyChanged("LoggerText");
}

get
{
return _loggerText;
}
}

免责声明:上面的代码是在没有编译器的情况下编写的。

关于c# - 模型更改后如何更新 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25364450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com