我正在尝试为绑定到ViewModel的软件创建自定义输出窗口。通常在过去我总是使用TextBox并使用appendText()
方法写入输出窗口。当然,使用ViewModel并尝试绑定到文本框,您似乎只能绑定到Text
属性。以下是我想要做的事情:
XAML:
<TextBox Text="{Binding Output}"></TextBox>
C#
public class ViewModel : DependencyObject
{
public static readonly DependencyProperty OutputProperty = DependencyProperty.Register("Output", typeof(ObservableCollection<string>), typeof(MVVMTestViewModel), new UIPropertyMetadata(null));
public ObservableCollection<string> Output
{
get
{
return (ObservableCollection<string>)GetValue(OutputProperty);
}
set
{
SetValue(OutputProperty, value);
}
}
public ViewModel()
{
Output = new ObservableCollection<string>();
}
public void OutputMessage(string message)
{
Output.Add(message);
}
}
当然这是不可能的,因为Text无法分配给Observable Collection。
注意:我可以使用ListView或ListBox并使用可观察的集合。但我不喜欢选择模式。我希望能够突出显示TextBox的文本,以便我可以将其复制并粘贴到Window之外。 isReadOnly
属性允许我相当容易地做到这一点。
有一种简单的方法吗?另一个控制我可能没有?
答案 0 :(得分:4)
我认为托马斯所说的是你可以在你的Window的代码隐藏中拥有以下内容:
public partial class MyWindow : Window
{
ViewModel _vm;
public MyWindow(ViewModel vm)
{
InitializeComponent();
_vm = vm;
_vm.Output.CollectionChanged += Output_CollectionChanged;
}
void Output_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
foreach(object item in e.NewItems)
{
outputTextBox.AppendText(item.ToString());
}
}
}
这样,窗口类将自动附加添加到Output集合的任何文本。
另一种方法(虽然它可能不被视为纯MVVM)是通过使用如下接口:
public interface IAppendOutput
{
void Append(string text);
}
public partial class MyWindow : Window, IAppendOutput
{
public MyWindow()
{
InitializeComponent();
}
public void Append(string text)
{
outputTextBox.AppendText(text);
}
}
public class ViewModel
{
IAppendOutput _outputter;
public ViewModel(IAppendOutput outputter)
{
_outputter = outputter;
}
public void AppendOutput(string text)
{
_outputter.Append(text);
}
}
然后在你的主应用程序中:
...
MyWindow window = new MyWindow();
ViewModel vm = new ViewModel(window);
window.DataContext = vm;
window.Show();
vm.AppendOutput("This is a test.");
...
这种方式可能不是最好的方法,但它可能是一种在其他情况下编写快速管道磁带代码的有用方法。它仍然是单元可测试的,因为ViewModel不了解窗口本身,只知道接口。它仍然是灵活的,因为您可以自定义任何类型的对象,以便它实现IAppendOutput接口。
答案 1 :(得分:1)
您可以使用转换器将集合转换为字符串:
public class ListToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
IEnumerable lst = value as IEnumerable;
if (lst != null)
{
StringBuilder sb = new StringBuilder();
foreach(var item in lst)
{
sb.AppendLine(item.ToString());
}
return sb.ToString();
}
return null;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}