我理解WPF在XAML中公开自定义属性的标准方法是在View的代码隐藏中将其定义为DependencyProperty
。
但是,这仅适用于DependencyObject
,例如UserControl
。然而,在干净的Prism方式中,我的代码隐藏(即,派生自UserControl
的类)是空的,我处理我的视图模型中的所有逻辑,它来自BindableBase
,这是不是DependencyObject
的儿童班。
考虑以下XAML片段:
<MyNamespace:MyCustomView MyProperty={Binding} />
MyCustomViewModel
的核心是
private string myProperty;
public string MyProperty {
get { return myProperty; }
set { SetProperty(ref myProperty, value); }
我对Prism来说还是比较新的。我该怎么做才能公开我MyProperty
中定义的MyCustomViewModel
,以便我可以在XAML中使用与上述类似的标记进行设置?
按照@ mm8的回答和我们在相应评论中的讨论,我开发了一个关于我的想法的最小(非)工作示例。摘要首先:
XAML很简单。
<Window x:Class="MyProject.Views.MainWindow"
Name="MainWindowName"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:MyNamespace="clr-namespace:MyProject.Views"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="{Binding Title}" Height="350" Width="525">
<ItemsControl ItemsSource="{Binding StringCollection, ElementName=MainWindowName}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<MyNamespace:MyUserControl MyTargetProperty="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
代码隐藏包含数据模型定义;实际上,我当然会在Models
命名空间中定义它。
using System.Collections;
using System.Windows;
namespace MyProject.Views {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
StringCollection = new ArrayList();
StringCollection.Add("String 1");
StringCollection.Add("String 2");
StringCollection.Add("String 3");
}
private ArrayList stringCollection;
public ArrayList StringCollection {
get { return stringCollection; }
set { stringCollection = value; }
}
}
}
视图模型是Prism代码模板提供的标准模型。
using Prism.Mvvm;
namespace MyProject.ViewModels {
public class MainWindowViewModel : BindableBase {
private string _title = "Prism Unity Application";
public string Title {
get { return _title; }
set { SetProperty(ref _title, value); }
}
public MainWindowViewModel() {
}
}
}
这是有趣的开始。最后,我想访问MyTargetProperty
中的MyUserControlViewModel
,因为我想在其上调用依赖于数据模型的其他工作的复杂程序逻辑,因此不是放在代码隐藏中。
很天真;只包含一个标签。
<UserControl x:Class="MyProject.Views.MyUserControl"
Name="UserControlName"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True">
<Label Content="{Binding MyTargetProperty, ElementName=UserControlName}" Background="AliceBlue"/>
</UserControl>
这是我将目标属性声明为DependencyProperty
的地方,正如@ mm8的答案所示。
using System.Windows;
using System.Windows.Controls;
namespace MyProject.Views {
/// <summary>
/// Interaction logic for MyUserControl
/// </summary>
public partial class MyUserControl : UserControl {
public MyUserControl() {
InitializeComponent();
}
public static readonly DependencyProperty MyTargetPropertyProperty = DependencyProperty.Register("MyTargetProperty", typeof(string), typeof(MyUserControl));
public string MyTargetProperty {
get { return (string)GetValue(MyTargetPropertyProperty); }
set { SetValue(MyTargetPropertyProperty, value); }
}
}
}
视图模型定义源属性。
using Prism.Mvvm;
namespace MyProject.ViewModels {
public class MyUserControlViewModel : BindableBase {
public MyUserControlViewModel() {
}
private string mySourceProperty;
public string MySourceProperty {
get { return mySourceProperty; }
set { SetProperty(ref mySourceProperty, value); }
}
}
}
我无法终身了解如何访问我在MainWindow
视图模型中ItemTemplate
的{{1}}中设置的值。
答案 0 :(得分:0)
只有目标(视图)属性必须是依赖项属性。因此,为了能够将任何绑定到这样的属性,在这种情况下它必须是MyProperty
之类的依赖属性:
<MyNamespace:MyCustomView MyProperty="{Binding SourceProperty}" />
视图模型中的 source 属性可能是一个普通的CLR属性:
public string SourceProperty { get; set; }
因此,您的视图模型不必(也不应该!)从DependencyObject
继承,但视图应该。