在我的程序中,我正在尝试设计一个输出窗口来显示日志记录信息。现在,我正在绑定一个字符串,并在日志数据进入后立即更新信息。
前:
<FlowDocument>
<Paragraph>
<Run DataContext="{Binding}" Text="{Binding OutputText}"/>
</Paragraph>
</FlowDocument>
(流文档位于富文本框内)
在我的viewmodel中,这就是我更新输出文本的方式
OutputText += loggingInfoString;
问题是字符串是不可变的数据类型,我不喜欢每次新数据进入时创建新字符串的想法。这是一个不必要的开销。
RichTextBox有一个名为AppendText的方法,我假设它会使用类似Stringbuilder的东西来添加到字符串中。我遇到的问题是能够访问ViewModel中的AppendText。
我考虑过在ViewModel中创建一个RichTextBox实例,并将RichTextBox绑定到ViewModel中的一个。我认为这违反了MVVM,但我并不完全确定。还有另一种方法可以解决这个问题吗?或者我应该在ViewModel中创建RichTextBox实例吗?
例: // ViewModel
RichTextBox Output;
//更新方法
Output.AppendText(loggerInfoText);
// Xaml
<RichTextBox DataContext="{Binding Output}" />
提前致谢!
答案 0 :(得分:2)
您可以创建一个类似的界面
interface IAppender{
void Append(string appendText);
}
您将此接口注入到viewmodel中,然后在视图中实现它。 这意味着您只需在viewmodel代码中执行
appender.Append(loggerInfoText);
在您的视图中,您通过向richtext添加文本来实现界面。 基于view和viewmodel的实现,根据viewmodel的创建位置,您可以在viewmodel中注入接口。假设在视图中创建了viewmodel,你得到这样的东西:
class View : UserControl, IAppender{
View(){
InitializeComponent();
DataContext = new YourViewModel(this);
}
void Append(string appendText){
//add text to richttext
}
}
public class YourViewModel : ViewModelBase{
private IAppender _appender;
public YourViewModel(IAppender appender){
_appender = appender;
}
}
这应该让你开始我希望 请注意,这是伪代码,未经测试甚至没有通过编译器运行。 将richttext传递给viewmodel确实不是MVVM。我们的想法是分离关注点。通过我的界面方法,这不会被违反。
答案 1 :(得分:-1)
作为注入依赖项的替代方法(即使解耦,使得视图中的注入令人痛苦),这是由您的控件实现的:
首先,您可以在内部使用StringBuilder来构建字符串。
public class MyViewModel : ViewModelBase
{
private StringBuilder sb;
private string Content
{
return sb.ToString();
}
protected Append(string text) {
sb.Append(text);
PropertyChanged("Content");
}
}
然后将Content
属性绑定到您的XAML元素。这样您就不会在ViewModel中进行分配/解除分配,并且您不需要麻烦地将DI注入ViewModel(即使它被接口抽象)。
但是,这假设您将在任何地方避免这种分配。如果您只想在某种类型的应用程序(即Windows应用商店应用程序)中使用它,而不是在ASP.NET或桌面应用程序中,则第二种替代方案可能更具吸引力(特别是对于其他类似方案):
您可以使用自定义行为来实现此目标,如this question中的答案所示。行为是可重用的,您无需在ViewModel中执行此类决策,从而允许您针对每个平台甚至每个View进行不同的处理。
它简化了您的ViewModel,您不必费心如何将实现IAppender
的View注入ViewModel(可能会导致View-first方法出现问题,其中View由IoC解决)并将ViewModel注入View中设置为DataContext)