2015-02-09 52 views
1

在我的程序中,我试图设计一个输出窗口来显示日志信息。对于现在我结合为一个字符串,并尽快日志数据进入更新信息在viewmodel中创建控件实例

例:

<FlowDocument> 
    <Paragraph> 
     <Run DataContext="{Binding}" Text="{Binding OutputText}"/> 
    </Paragraph> 
</FlowDocument> 

(流文件是一个丰富的文本框内)

在我的视图模型,这是我如何更新我的outputText

OutputText += loggingInfoString; 

的问题是,字符串是不可变的数据类型,我不喜欢创建一个新的字符串,每一次新的大的想法ta进来。这是一个不必要的开销。

RichTextBox中有一个名为AppendText通过方法,我认为将使用类似一个StringBuilder,以添加到字符串。我遇到的问题是能够访问ViewModel中的AppendText。

我想过让视图模型内的RichTextBox的实例,并结合在RichTextBox到一个在视图模型。我认为这违反了MVVM,但我不完全确定。还有另外一种方法可以解决这个问题吗?或者我应该在ViewModel中创建RichTextBox实例?

例: //视图模型

RichTextBox Output; 

//更新方法

Output.AppendText(loggerInfoText); 

// XAML中

<RichTextBox DataContext="{Binding Output}" /> 
提前

谢谢!

回答

2

创建像这样

interface IAppender{ 
    void Append(string appendText); 
} 

可以注入该接口到您的视图模型的接口,你实现它在您的观点。 这意味着,在您的视图模型的代码,你根本就

appender.Append(loggerInfoText); 

而且在你看来,你通过添加文本到富文本实现的接口。 根据您的视图和视图模型的实现,根据视图模型的创建位置,您可以在视图模型中注入接口。假设视图模型在视图中创建你得到的东西是这样的:

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。这个想法是有关的分离。通过我的界面方法,这不会被违反。

+0

太棒了!感谢您的迅速回复。我不相信我甚至没有想到这一点。有时候作为程序员,我们忽略了最简单的事情。再次感谢:) – CodingMadeEasy 2015-02-09 21:04:17

+0

我有一个快速的问题。如果我在viewmodel中有一个事件处理程序。将appendtext添加到视图模型的事件处理程序是否是不好的做法? – CodingMadeEasy 2015-02-10 15:40:49

+0

取决于你的意思。调用从注入到视图模型的接口追加,并在事件处理程序中执行,这不是问题。事件处理程序本身不应附加到WPF组件事件。使用命令,甚至行为。但这已经是MVVM的更高级了。很难看到你需要从这一端;-) – 2015-02-10 17:40:16

-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不同地处理这种决定。

它简化了您的视图模型,你就不必费心如何注入实现了IAppender到您的视图模型视图(可能会导致查看优先的方法,其中查看被国际奥委会和得到解决烦恼注入视图的ViewModel设置为DataContext)

+0

如果我使用StringBuilder,它与使用字符串没有区别,但实际上会更糟糕。每次追加字符串生成器时,我都会将其转换为字符串。所以基本上我会追加一个字符串生成器,然后生成一个字符串,这正是我想要避免的。 – CodingMadeEasy 2015-02-11 15:14:41