【发布时间】:2014-11-06 14:22:06
【问题描述】:
我目前正在尝试掌握 MVVM 的概念。因此,我已经阅读了几篇博客并查看了一些项目。但是,我仍然不知道如何应用这个概念。
现在,我正在尝试将字符串值的 ObservableCollection 绑定到 ListBox,以便逐行列出它们的值。我的 ViewModel 目前看起来像这样:
namespace TestApp.ViewModel
{
class StatusViewModel : NotifyPropertyChanged
{
private string _newMsg;
private readonly ObservableCollection<string> _history = new ObservableCollection<string>();
public string Print
{
get { return _newMsg; }
set
{
_newMsg = value;
RaisePropertyChangedEvent("History");
AddToHistory(_newMsg);
}
}
public IEnumerable<string> History
{
get { return _history; }
}
private void AddToHistory(string item)
{
if (!_history.Contains(item))
_history.Add(item);
}
}
}
namespace TestApp.ViewModel
{
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
在视图中,我想将 ListBox 绑定到 History。这是我的 XAML:
<UserControl x:Class="TestApp.View.StatusView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:TestApp.ViewModel" mc:Ignorable="d">
<UserControl.Resources>
<vm:StatusView x:Key="statusView"/>
</UserControl.Resources>
<Grid DataContext="{StaticResource statusView}">
<GroupBox Header="StatusView">
<ListBox x:Name="StatusListBox" ItemsSource="{Binding History, Source={StaticResource statusView}}"/>
</GroupBox>
</Grid>
</UserControl>
当我启动 TestApp 时,我需要访问我的 StatusViewModel 的实例,以便将字符串添加到我的 ObservableCollection。我想知道这是怎么做到的:
using TestApp.ViewModel;
namespace TestApp.Controller
{
public partial class Startup
{
private void StartTestApp()
{
// from where do I get my 'statObj' in order to do:
statObj.Print = "something";
}
}
}
如何将我的 StatusViewModel 对象中的字符串 ObservableCollection 绑定到列表框?
更新:
感谢大家的精彩 cmets!现在,我知道我需要持有我的 ViewModel 的一个实例,以便从 View 和 Controller 访问它。但是,我仍在努力以正确的方式做到这一点。## Heading ##
现在,我首先在用户控件的代码隐藏中创建实例。虽然它正在工作,但我不喜欢我必须在我的视图中引用 ViewModel。我想,MVVM 的全部意义在于不这样做。
此外,我想知道如何在视图之外访问我新实例化的 StatusViewModel 状态,例如在名为 Controller 的不同命名空间中。
using System.Windows.Controls;
using TestApp.ViewModel;
namespace TestApp.View
{
/// <summary>
/// Interaction Logic for StatusView.xaml
/// </summary>
public partial class StatusView : UserControl
{
public StatusView()
{
InitializeComponent();
this.DataContext = new StatusViewModel();
}
public TestApp.ViewModel.StatusViewModel State
{
get { return (DataContext as TestApp.ViewModel.StatusViewModel); }
}
}
}
【问题讨论】:
-
绑定将在
Status:<vm:Status x:Key="status"/>的这个实例上工作,并且为了测试你创建Status的不同实例 并在上面更改Print。它们不是同一个对象 -
有道理!但是如何在我的
StartTestApp方法中编辑现有的状态对象?我的 start 方法位于不同的命名空间中,名为TestApp.Controller。 -
您需要获取该实例。取决于你的设计。有些人使用包含视图模型定位器的框架。我通常将我的 VM 定义为 app.xaml 中的资源,然后将它们相互绑定,因此 VM X 具有对 VM Y 的引用。有些人在视图的构造函数中构造它们,因此他们具有对它的引用.随心所欲。