我一直试图在 WPF 中设置这个障碍,并且我认为我已经找到了一个解决方案,尽管它是一个丑陋的解决方案。
场景如下:
- 我有一个带有自定义依赖属性的自定义用户控件。
- 用户控件可以嵌套在我的其他用户控件中。
- 我的每个用户控件都有一个由定位器指定的数据上下文(我遵循 MVVM 模式)
- 我想将自定义依赖属性绑定到父视图模型中的值。
代码...
父视图
<UserControl DataContext="{Binding Source={StaticResource Locator}, Path=ParentControlLocator}">
<my:Child Demo="{Binding Path=DataContext.DemoTextAlpha, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl, AncestorLevel=1}}" />
</UserControl>
父类视图模型
public class ParentClassViewModel : BaseViewModel
{
private string _demoTextAlpha = "Some Alpha text";
public string DemoTextAlpha
{
get
{
return this._demoTextAlpha;
}
set
{
this._demoTextAlpha = value;
this.NotifyPropertyChange("DemoTextAlpha");
}
}
}
子视图
<UserControl DataContext="{Binding Source={StaticResource Locator}, Path=ChildControlLocator}">
<TextBlock Text="{Binding Path=SomeProperty}" />
</UserControl>
子视图代码后面
public partial class Child : UserControl
{
public Child()
{
InitializeComponent();
}
public static readonly DependencyProperty DemoProperty =
DependencyProperty.Register("Demo",
typeof(string),
typeof(Child),
new FrameworkPropertyMetadata()
{
PropertyChangedCallback = OnDemoChanged,
BindsTwoWayByDefault = true
});
public string Demo
{
get { return this.GetValue(DemoProperty).ToString(); }
set { this.SetValue(DemoProperty, value); }
}
private static void OnDemoChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (Child)d;
var viewModel = (ChildViewModel)control.DataContext;
viewModel.SomeProperty = (string)e.NewValue;
}
}
子视图模型
public class ChildViewModel : BaseViewModel
{
private string _someProperty;
public string SomeProperty
{
get
{
return _someProperty;
}
set
{
_someProperty = value;
this.NotifyPropertyChange("SomeProperty");
}
}
}
好的,所以这个WORKS。我想要实现的是更好/更优雅的代码,特别是关于这个声明。
<my:Child Demo="{Binding Path=DataContext.DemoTextAlpha, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl, AncestorLevel=1}}" />
即使我可以忍受,就优雅而言,但现在困扰我的一件事是当我打字时
Path=DataContext.DemoTextAlpha
当我尝试深入 DataContext 时,智能感知下降。所以我必须格外小心才能正确输入所有内容。
那么 - 是否有任何不同的方法可以使 DataContext 的属性出现在智能感知中,或者是否有另一种方法来实现我现在正在做的同样的事情?
谢谢。
编辑澄清
当我放这样的东西而不是像上面的例子中指定相对源时......
<my:Child Demo="{Binding DemoTextAlpha}"/>
我收到一个错误...
System.Windows.Data Error: 40 : BindingExpression path error: 'DemoTextAlpha' property not found on 'object' ''ChildViewModel' (HashCode=34126977)'. BindingExpression:Path=DemoTextAlpha; DataItem='ChildViewModel' (HashCode=34126977); target element is 'Child' (Name=''); target property is 'Demo' (type 'String')