gpt4 book ai didi

wpf - 从 XAML 设置 ViewModel 属性值

转载 作者:行者123 更新时间:2023-12-04 20:54:23 26 4
gpt4 key购买 nike

我有一个在 XAML 中声明的 View (见下文)。关联的 View 模型是使用 MEF 自动创建的。我希望能够做这样的事情:

<local:MyControl Owner={x:Static local:Owners.ProjectOwner} />

期望的净效果是将某些 View 模型属性设置为等于 Owners.ProjectOwner。

我可以使用 hacky 代码隐藏实现所需的结果,但宁愿通过绑定(bind)或类似的方式来实现。任何人都可以建议这样做的方法吗?

更新

我辞职写了一个行为。但是,我并没有为一个特定案例付出所有努力,而是对我的解决方案进行了通用化,并将其包含在下面以防万一有人感兴趣。这是一种混合行为(System.Windows.Interactivity.dll),但也可以很容易地成为传统的附加行为。
using System;
using System.Windows;
using System.Windows.Interactivity;

namespace BlendBehaviors
{
public class SetViewModelPropertyBehavior : Behavior<FrameworkElement>
{
public static readonly DependencyProperty PropertyNameProperty =
DependencyProperty.Register("PropertyName", typeof(string), typeof(SetViewModelPropertyBehavior));

public static readonly DependencyProperty PropertyValueProperty =
DependencyProperty.Register("PropertyValue", typeof(object), typeof(SetViewModelPropertyBehavior));

public SetViewModelPropertyBehavior()
{ }

public string PropertyName
{
get { return (string)GetValue(PropertyNameProperty); }
set { SetValue(PropertyNameProperty, value); }
}

public object PropertyValue
{
get { return GetValue(PropertyValueProperty); }
set { SetValue(PropertyValueProperty, value); }
}

protected override void OnAttached()
{
base.OnAttached();
var ao = AssociatedObject;
SetViewModel(ao.DataContext);
ao.DataContextChanged += FrameworkElement_DataContextChanged;
}

protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.DataContextChanged -= FrameworkElement_DataContextChanged;
}

private void FrameworkElement_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
SetViewModel(e.NewValue);
}

private void SetViewModel(object viewModel)
{
SetViewModelProperty(viewModel, PropertyName, PropertyValue);
}

private static void SetViewModelProperty(object viewModel, string propertyName, object propertyValue)
{
if (viewModel == null || propertyName == null) {
return;
}
var info = viewModel.GetType().GetProperty(propertyName);
if (info != null && CanAssignValue(propertyValue, info.PropertyType)) {
info.SetValue(viewModel, propertyValue, null);
}
}

private static bool CanAssignValue(object value, Type targetType)
{
if (value == null) {
return !targetType.IsValueType || Nullable.GetUnderlyingType(targetType) != null;
}
return targetType.IsAssignableFrom(value.GetType());
}
}
}

然后像这样使用它:
<local:MyControl>
<i:Interaction.Behaviors>
<bb:SetViewModelPropertyBehavior PropertyName="Owner" PropertyValue="{x:Static local:Owners.ProjectOwner}" />
<bb:SetViewModelPropertyBehavior PropertyName="AnotherProperty" PropertyValue="{StaticResource MyResourceKey}" />
</i:Interaction.Behaviors>
</local:MyControl>

最佳答案

任何 WPF 绑定(bind)的目标必须是 DependencyProperty .来源可以是 DependencyProperty , 一个实现 INotifyPropertyChanged 的 CLR 对象,或者只是一些对象。可以通过更改 Binding.Mode 来交换目标和源。属性(property)。

但在这种情况下,绑定(bind)中的一项是静态解析的属性 (Owners.ProjectOwner)。因此,它不是 DependencyProperty .因此,它只能作为来源出现。因此,您将其绑定(bind)到(目标)的必须是 DependencyProperty .因此,它不能是您的 View 模型上的属性(假设您尚未创建基于 DependencyObject 的 View 模型,即 a mistake )。

因此,您不能直接将 VM 上的属性绑定(bind)到静态属性。不过,您可以编写一个附加的行为来为您执行此操作。

关于wpf - 从 XAML 设置 ViewModel 属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6303849/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com