我正在处理多文档查看器(一个带有自定义控件的简单窗口,每个窗口都有一个单独的视图模型)。单击文件名时,会在主窗口中添加用户控件的新实例。用户控件具有依赖项属性,该属性保存文件名的路径,该文件名在其后面的代码隐藏中定义。现在我想知道如何从用户控件获取此属性的值到viewmodel,因此它可以显示实际文档。任何提示?
<ctrl:DocViewerControl x:Key="docviewer" DocumentSource="{Binding SelectedItem.Path, ElementName=docList}"/>
我在主窗口中使用此代码来创建我的用户控件的新实例,其中DocumentSource是我需要访问的依赖属性,如上所述。
修改
以下是视图的(相关)代码和我的控件的viewmodel,特定于我所拥有的依赖属性值捕获问题。
UserControl.xaml.cs
public partial class ToolboxControl : UserControl
{
public static readonly DependencyProperty DocumentSourceProperty = DependencyProperty.Register("DocumentSource",
typeof(string), typeof(ToolboxControl), new UIPropertyMetadata(new PropertyChangedCallback(OnDocumentSourceChanged)));
public ToolboxControl()
{
InitializeComponent();
}
public string DocumentSource
{
get { return (string)GetValue(DocumentSourceProperty); }
set { SetValue(DocumentSourceProperty, value); }
}
private static void OnDocumentSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
}
}
PV_ViewModel.cs
public class PV_ViewModel : ObservableObject
{
.....
public string DocumentSource
{
get { return (String.IsNullOrEmpty(_documentsource)? (_documentsource = @"about:blank") : _documentsource); }
set { SetField<string>(ref _documentsource, value, "DocumentSource"); }
}
.....
public PV_ViewModel()
{
PropertyChanged += DocumentSourceChanged;
}
.....
protected void DocumentSourceChanged(object sender, PropertyChangedEventArgs e)
{
if (sender != null)
{
switch(e.PropertyName)
{
case "DocumentSource":
{
// show the document and whatsoever
break;
}
}
}
}
.....
}
尽管MainWindow中的UserControl使用当前文档路径字符串填充了DocumentSourceProperty,但getter和viewmodel DocumentSource属性的setter都不会从任何地方访问。 (我可以在主应用程序中看到它形成当前打开的文档的集合。)
澄清:应用程序解决方案包含MainWindow项目(主视图,带有TreeView和UserControl容器的简单窗口),UserControl项目((希望)独立应用程序,用于在提供路径时显示单个文档通过DocumentSource属性显示的文档。
答案 0 :(得分:0)
我不确定我是否理解您的问题(或者您了解依赖属性如何工作),因此您可能需要发布更多代码(例如DI)
通常,您的DocViewerControl
看起来像这样
public abstract class DocViewerControl : UserControl
{
public string Path
{
get { return (string)GetValue(PathProperty); }
set { SetValue(PathProperty, value); }
}
public static readonly DependencyProperty PathProperty =
DependencyProperty.Register("Path", typeof(string), typeof(DocViewerControl), new PropertyMetadata(string.Empty));
}
这将在控件的XAML中公开一个Property。
这里重要的是你将它设为TwoWay绑定,因此UserControll的任何更改都将更新ViewModel中的有界字段。
您的ViewModel:
public class Doc1ViewModel : ViewModelBase {
private string path;
public string Path
{
get { return path;}
set {
if(path!=value) {
path = value;
OnPropertyChanged("Path");
}
}
}
}
现在,每次在 UserControl 中分配属性时,ViewModel中的值都会更新。如您所见,Dependency属性由两个属性组成。一个名为static
的{{1}}依赖项属性和一个名为PathProperty
的实例属性。
但是仔细看看它,它根本不是真正的实例属性。它只是使用Path
和GetValue
(它们是从每个UI控件继承的DependencyObject类派生而来)包围Dependency属性的调用。
希望这可以清除Dependency Properties的工作原理,因为很难在没有看到代码的情况下判断出你的方法有什么问题。
简而言之,依赖属性(与附加属性一起)使用TwoWay可绑定属性扩展XAML代码(普通实例属性只能在一个方向上绑定)。