在网站上搜索了很多并阅读了很多类似的问题,但似乎没有解决我用户控件无法理解的问题 .
我有一个用MVVM实现的用户控件 . 基本上是一个文件夹网格,其中每个文件夹都是一个复选框和一个路径 . 用户可以选中任何检查复选框的文件夹 . User Control xaml 是:
<UserControl x:Class="TestDP.Views.ViewCTRL" [...]>
<DataGrid Name="GridMain" ItemsSource="{Binding Folders}">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Cked" Binding="{Binding Cked, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Path" Binding="{Binding Path}"/>
</DataGrid.Columns>
</DataGrid>
</UserControl>
User control code behind 是:
public partial class ViewCTRL : UserControld
{
public static DependencyProperty SelectedFoldersProperty =
DependencyProperty.Register("SelectedFolders", typeof(ObservableCollection<Folder>), typeof(ViewCTRL),
new FrameworkPropertyMetadata() { BindsTwoWayByDefault = true });
public ObservableCollection<Folder> SelectedFolders
{
get{return (ObservableCollection<Folder>)GetValue(SelectedFoldersProperty);}
set{SetValue(SelectedFoldersProperty, value);}}
public ViewCTRL()
{
var vm = new ViewCTRLModel();
InitializeComponent();
GridMain.DataContext = vm;
// bindings
SetBinding(SelectedFoldersProperty, new Binding()
{
Source = GridMain.DataContext,
Path = new PropertyPath("SelectedFoldersV"),
UpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged,
Mode = BindingMode.TwoWay
});
}
User Control ViewModel 是:
public class ViewCTRLModel : INotifyPropertyChanged
{
[...]
public void Folder_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
SelectedFoldersV = new ObservableCollection<Folder>(Folders.Where(x => x.Cked));
}
private ObservableCollection<Folder> folders;
public ObservableCollection<Folder> Folders
{
get{return folders;}
set{folders = value;OnPropertyChanged("Folders");}
}
private ObservableCollection<Folder> selectedFoldersV;
public ObservableCollection<Folder> SelectedFoldersV
{
get{return selectedFoldersV;}
set{selectedFoldersV = value;OnPropertyChanged("SelectedFoldersV");}
}
[...]
}
然后我使用WPF应用程序,我放置了我的用户控件 . 如果我将用户控件DP SelectedFolders绑定到 ItemSource ,则一切正常 . 如果我检查用户控件的文件夹复选框,则选择项目源上的SelectedFolder .
<Window x:Class="TestDPWPF.Views.ViewWPF" [...]>
<uc:ViewCTRL Name="ViewCTRL" />
<ListBox ItemsSource="{Binding ElementName=ViewCTRL, Path=SelectedFolders}" DisplayMemberPath="Path"/>
If I Bind the SelectedFolders Propery to a Property of the Window view model like :
<uc:ViewCTRL Name="ViewCTRL" SelectedFolders="{Binding SelectedFoldersVMWPF, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
the usercontrol get the initial values passed by the window viewmodel but then binding seems broken and selecting any folder does not update the SelectedFoldersVMWPF binding.
Viewmodel of the windows 是:
class ViewWPFModel : INotifyPropertyChanged
{
public ViewWPFModel()
{
SelectedFoldersVMWPF = new ObservableCollection<Folder>();
SelectedFoldersVMWPF.Add(new Folder() { Path = "uuu" });
}
private ObservableCollection<Folder> selectedFoldersVMWPF;
public ObservableCollection<Folder> SelectedFoldersVMWPF
{
get {return selectedFoldersVMWPF;}
set {selectedFoldersVMWPF = value; OnPropertyChanged("SelectedFoldersVMWPF");}
}
}
我在输出窗口中没有关于绑定的任何消息,因此所有绑定路径都应该没问题 . 我认为窗口视图模型和控件的DP之间的绑定是由用户控件和用户控件视图模型之间的绑定决定的 . 但我不知道为什么以及如何解决这个问题 . 我尝试以多种方式更改用户控件的DataContex,但结果始终相同 . 任何人都可以带领我朝着正确的方向前进
1 回答
在第一个示例中,ViewCTRL的SelectedFolders DependencyProperty绑定到ViewCTRLModel的SelectedFoldersV . 然后将ListBox的ItemsSource绑定到SelectedFolders DependencyProperty .
在第二个示例中,ViewCTRL的SelectedFolders DependencyProperty绑定到ViewWPFModel的SelectedFoldersVMWPF属性(在ViewCTRL构造函数的InitializeComponent()调用期间) . 但随后紧接着,通过SetBindings调用将Binding更改为ViewCTRLModel的SelectedFoldersV .
我之前没有这样做过,但我认为如果你在ViewModel中将SelectedFoldersV更改为DependencyProperty并对ViewCTRL构造函数进行以下更改,这应该可行:
请注意,可能有更好的方法来实现您尝试执行的操作(例如使用MVVM Light的Messenger在ViewModel之间传递这些类型的更改) . 我个人不希望将一堆绑定链接在一起,因为我认为这更令人困惑 .