我很新的WPF和现在遇到的情景是我找不到任何有效的解决方案。 在项目中,我有很多的ViewModels和用户控件。 主窗口splited成两个并在左手侧I根据当前视图模型everythis工作正常显示用户控件。 当我想根据在左手侧选择哪些用户在右手侧显示第二用户控件的问题开始。 用户控件有很多文本框和组合框。 我将如何绑定从cosequtive视图模型这些数据?
//mainwindow.xaml
<Window.resources>
<Datatemplate Datatype={x:Type vm:Viewmodel1}>
<loc:Usercontrol1/> // in the left hand side
</DataTemplate>
<Datatemplate Datatype={x:Type vm:Viewmodel2}>
<loc:Usercontrol2/> // in the lefthand side
</DataTemplate>
</Window.Resources>
...
<Grid Grid.Column="0">
<ContentControl Content={Binding CurrentViewModel}/>
</Grid>
<Grid Grid.Column="1">
<Grid.Resources>
<Datatemplate Datatype={x:Type vm:Viewmodel1}>
<loc:Usercontrol3 NameDp={Binding Name}/> // in the right hand side
</DataTemplate>
<Datatemplate Datatype={x:Type vm:Viewmodel2}>
<loc:Usercontrol3/> // in the rightthand side
</DataTemplate>
</Grid.Resources>
</Grid>
// Usercontrol3.xaml
<Grid>
<TextBox Text="{Binding Path=NameDp, ElementName=UserControl3}" />
</Grid>
// UserControl3.cs
public static readonly DependencyProperty NameUCProperty =DependencyProperty.Register("NameDp", typeof(string), typeof(UserControl3), new FrameworkPropertyMetadata(NamePropertyChanged));
public string NameDp
{
get
{
return (string)GetValue(NameUCProperty);
}
set
{
SetValue(NameUCProperty, value);
}
}
//ViewModel
Public Name {get;set;}
在每一个的ViewModels我从数据库获取数据,我想根据用户选择绑定在右侧将数据发送给用户控件。 如何绑定这些数据? 这是正确的计算策略还是我完全地错了吗?
这绝对做到这一点的方法之一。 对于我来说,我会整理东西这样。 我有一个原型在这里演示这些东西是如何工作的?
首先,我们的主窗口
<Window x:Class="WpfUserControlsBindingListeningNotMuchHere.MainWindow"
xmlns:t="clr-namespace:WpfUserControlsBindingListeningNotMuchHere"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:ms="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Window.DataContext>
<t:ViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<t:UserControl1 x:Name="uc1"
Items="{Binding Items}"
Selected="{Binding Selected, Mode=TwoWay}" />
<t:UserControl2 Grid.Column="1"
DataContext="{Binding Result}" />
</Grid>
</Window>
注意UC1。 这需要在列表中,并公开选定的项目。 这些都绑定到视图模型。 性能Items
和Selected
是我已经在用户控件定义DependencyProperties。 我可以显示的代码,如果你想要的,但它应该是不理解的。 (该Mode=TwoWay
可以免掉,如果我调整了DP的定义。)
在视图模型,我听更改Selected
,并相应地做我的工作。
class ViewModel : INotifyPropertyChanged
{
private object _selected;
private object _result;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<object> Items { get; private set; }
public object Selected
{
get { return this._selected; }
set
{
if (_selected == value)
return;
this._selected = value;
PropertyChanged(this, new PropertyChangedEventArgs("Selected"));
}
}
public object Result
{
get { return this._result; }
set
{
if (_result == value )
return;
this._result = value;
PropertyChanged(this, new PropertyChangedEventArgs("Result"));
}
}
public ViewModel()
{
Items = new ObservableCollection<object>();
Items.Add(1);
Items.Add("hello");
Items.Add(3.0d);
PropertyChanged += OnPropertyChanged;
}
private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "Selected")
return;
//DO MASSIVE WORK HER ON BACKGROUND THREAD OR SOMETHING LOL
Result = "OMG THIS TOOK A LONG TIME, " + Selected.ToString();
}
}
所以,我只是看一换到选定的,在这一点上,我做我的工作(业务逻辑)和另一个属性中暴露的结果。 这则绑定到我的UI第二用户控件。
正如我所说的,在UC的代码是微不足道的...
<UserControl x:Class="WpfUserControlsBindingListeningNotMuchHere.UserControl1"
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"
x:Name="root">
<ListBox ItemsSource="{Binding Items, ElementName=root}"
SelectedItem="{Binding Selected, ElementName=root}" />
</UserControl>
和在代码隐藏(OMG代码隐藏看出来EVIL)
public partial class UserControl1 : UserControl
{
#region Items
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(
"Items",
typeof(IEnumerable<object>),
typeof(UserControl1),
new UIPropertyMetadata(null));
public IEnumerable<object> Items
{
get { return (IEnumerable<object>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
#endregion
#region Selected
public static readonly DependencyProperty SelectedProperty =
DependencyProperty.Register(
"Selected",
typeof(object),
typeof(UserControl1),
new UIPropertyMetadata(null));
public object Selected
{
get { return (object)GetValue(SelectedProperty); }
set { SetValue(SelectedProperty, value); }
}
#endregion
public UserControl1()
{
InitializeComponent();
}
}
和
<UserControl x:Class="WpfUserControlsBindingListeningNotMuchHere.UserControl2"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TextBlock Text="{Binding}" />
</UserControl>
在这一个没有代码隐藏。