如何在 XAML 中创建模型并为其赋值



我有一些奇怪的情况,我正在尝试完成:

我有一个"转换器",要求我在参数中提供多个值。此值之一是类。我想创建一个包含这些参数的类:

<ContentControl ContentTemplateSelector="{StaticResource ConventionBasedDataTemplateSelector}" >
<ContentControl.Content>
<Binding Path="SelectedNode">
<Binding.Converter>
<converters:NodeToViewModel  />
</Binding.Converter>
<Binding.ConverterParameter>
<converters:NodeToViewModelParameters ViewContext="{x:Static viewModelRegister:ViewContext.LiveView}">
<converters:NodeToViewModelParameters.Parameters>
<converters:Parameters SomeParameter="{Binding Something}" SomeOtherParameter="{Binding SomethingElse}"/>
</converters:NodeToViewModelParameters.Parameters>
</converters:NodeToViewModelParameters>
</Binding.ConverterParameter>
</Binding>
</ContentControl.Content>
</ContentControl>

但是当它尝试将Something分配给SomeParameter时,我收到一个错误:

'A 'Binding' cannot be set on the 'SomeParameter' property of type 'Parameters'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.'

有没有办法从 XAML 创建模型,采用来自 ViewModel 的一些参数?

这试图将IValueConverter框架延伸得有点太远 - 你可以让你的转换器实现DependencyObject允许绑定,但我认为你会遇到麻烦,因为这些是如何从 xaml 实例化的。

我推荐 Microsoft.Xaml.Behaviors.Wpf nuget 包 - 这允许您附加Behavior已经扩展DependencyObject并支持开箱即用绑定的实例。绑定触发后,您可以通过所需的任何逻辑在附加到的ContentControl上设置Content

例如:

public class NodeToViewModelBehavior : Behavior<ContentControl>
{
public static readonly DependencyProperty NodeProperty = DependencyProperty.Register("Node", typeof(object), typeof(NodeToViewModelBehavior), new FrameworkPropertyMetadata(PropertyChangedCallback));
public object Node
{
get { return (object) GetValue(NodeProperty); }
set { SetValue(NodeProperty, value); }
}
private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var nodeToViewModelBehavior = (NodeToViewModelBehavior)d;
var newNode = e.NewValue;
nodeToViewModelBehavior.SetContent(newNode);
}
private void SetContent(object newNode)
{
var convertedObject = newNode; // insert logic here to grab whatever data you need
this.AssociatedObject.Content = convertedObject;
}
}

并在 xaml 中的用法如下:

<ContentControl>
<i:Interaction.Behaviors>
<local:NodeToViewModelBehavior Node="{Binding SelectedNode}"/>
</i:Interaction.Behaviors>
</ContentControl>

其中命名空间 i 声明为

xmlns:i="clr-namespace:Microsoft.Xaml.Behaviors;assembly=Microsoft.Xaml.Behaviors"

您可以创建一个实现两个接口的转换器,IValueConverter 和 IMultiValueConverter:

public class NodeToViewModel : IValueConverter, IMultiValueConverter
{
private object Convert(
object value, NodeToViewModelParameters parameters = null)
{
// do the actual conversion here, either with or without parameters
}
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
return Convert(value);
}
public object Convert(
object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Convert(
values[0],
new NodeToViewModelParameters
{
SomeParameter = values[1],
SomeOtherParameter = values[2]
});
}
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
public object[] ConvertBack(
object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}

然后将其与多重绑定一起使用:

<ContentControl.Content>
<MultiBinding>
<MultiBinding.Converter>
<converters:NodeToViewModel/>
</MultiBinding.Converter>
<Binding Path="SelectedNode"/>
<Binding Path="Something"/>
<Binding Path="SomethingElse"/>
</Binding>
</ContentControl.Content>

最新更新