我需要分别管理UI特定参数(View)和应用程序数据(Model / ViewModel),因此我使用View的代码隐藏作为第一个,以及一个单独的类(前缀为ViewModel)后来。这是我所拥有的简化版本:
查看(XAML)
<Window x:Class="UrSimulator.View.MyView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MyView" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding FirstColumnWidth}" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<Label>Width:</Label>
<TextBox Text="{Binding FirstColumnWidth}" IsReadOnly="True" Background="LightGray" />
</StackPanel>
<StackPanel Grid.Column="1">
<Label>First Column Width:</Label>
<TextBox Text="{Binding FirstColumnWidth}" />
<Label>View Model Data:</Label>
<TextBox Text="{Binding MyViewModel.PropertyFromVM}" />
<Label Content="{Binding MyViewModel.PropertyFromVM}" />
</StackPanel>
</Grid>
查看(代码隐藏)
public partial class MyView : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private MyViewModel m_MyViewModel;
public MyViewModel MyViewModel
{
get { return m_MyViewModel; }
set
{
m_MyViewModel = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("MyViewModel"));
}
}
private GridLength m_FirstColumnWidth;
public GridLength FirstColumnWidth
{
get { return m_FirstColumnWidth; }
set
{
m_FirstColumnWidth = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("FirstColumnWidth"));
}
}
public MyView()
{
MyViewModel = new MyViewModel();
DataContext = this;
FirstColumnWidth = new GridLength(100);
InitializeComponent();
}
}
视图模型
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string m_PropertyFromVM;
public string PropertyFromVM
{
get { return m_PropertyFromVM; }
set
{
m_PropertyFromVM = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("PropertyFromVM"));
}
}
public MyViewModel()
{
PropertyFromVM = "Some business data";
}
}
它有效,但我发现在指向VM的每个绑定上使用MyViewModel.
都很麻烦。
问题:
有没有其他方法可以在不使用前缀的情况下执行此操作?
如果不使用this
作为DataContext,我应该如何编写UI的绑定(width属性),我会使用:
DataContext = MyViewModel;
我做错了什么,这不是它的目的是什么?
注意:忘记Width所需的转换器,只要文本有效就行,并且不是我对问题的关注。
答案 0 :(得分:3)
DataContext = this;
Yuck ......:)
让视图模型成为数据上下文,并绑定到视图的属性,如下所示:
<Window x:Name="This" ...>
...
<SomeControl SomeProperty="{Binding MyViewProperty, ElementName=This}"/>
...
</Window>
旁注:
class MyView : Window, INotifyPropertyChanged
如果继承Window,为什么视图的属性不是“依赖属性”?
答案 1 :(得分:0)
这是做MVVM的一种方式,但不是一个很好的选择,因为你仍在使用紧密耦合的View
对象。
理想的情况是,让WPF通过将View
个对象绑定到ViewModel
的{{1}}属性并设置Content
来推断要使用的ContentPresenters
类。您DataTemplate
类型的条目。
这样,您甚至不需要在代码中的任何地方使用ViewModel
语句。
e.g。在App.xaml或类似的
中DataContext = blah
...然后在Window / UserControl / XAML中,只要你需要它......
<DataTemplate DataType={x:Type MyViewModel}>
<local:MyViewModelView/>
</DataTemplate>
...可以是另一个<ContentPresenter Content={Binding MyViewModelAsAProperty}/>
上的DependencyProperty
或标准INotifyPropertyChanged
已启用媒体资源。
答案 2 :(得分:-1)
在MyViewModel类
上添加此代码private MyView _ObjMyViewModel;
public MyView ObjMyViewModel
{
get { return _ObjMyViewModel; }
set
{
_ObjMyViewModel= value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("ObjMyViewModel"));
}
}
在XAML中
<Window.DataContext>
<ViewModel:MyViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ObjMyViewModel.FirstColumnWidth}" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<Label>Width:</Label>
<TextBox Text="{Binding ObjMyViewModel.FirstColumnWidth}" IsReadOnly="True" Background="LightGray" />
</StackPanel>
<StackPanel Grid.Column="1">
<Label>First Column Width:</Label>
<TextBox Text="{Binding ObjMyViewModel.FirstColumnWidth}" />
<Label>View Model Data:</Label>
<TextBox Text="{Binding MyViewModel.PropertyFromVM}" />
<Label Content="{Binding MyViewModel.PropertyFromVM}" />
</StackPanel>
我希望它的工作......