Как создать модель в XAML и присвоить ей значения - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть какой-то странный случай, который я пытаюсь выполнить:

У меня есть один «конвертер», который требует, чтобы я указывал кратные значения в параметрах.Одним из этих значений является класс.Я хотел создать класс, содержащий эти параметры:

<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?

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

Это попытка слишком растянуть структуру IValueConverter - вы могли бы сделать так, чтобы ваши конвертеры реализовали DependencyObject, чтобы разрешить связывание, но я думаю, что вы столкнетесь с проблемами, вызвав их запуск из-за того, как они создаются изxaml.

Я бы порекомендовал пакет nuget Microsoft.Xaml.Behaviors.Wpf - это позволяет подключать Behavior экземпляров, которые уже расширяют DependencyObject и поддерживают привязку изкоробка.После того, как привязка сработает, вы можете установить Content на ContentControl, к которому вы привязаны, с помощью любой логики, которую вы хотите.

Например:

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"
0 голосов
/ 25 сентября 2019

Вы можете создать конвертер, который реализует оба интерфейса, 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();
    }
}

Затем использовать его с MultiBinding:

<ContentControl.Content>
    <MultiBinding>
        <MultiBinding.Converter>
            <converters:NodeToViewModel/>
        </MultiBinding.Converter>
        <Binding Path="SelectedNode"/>
        <Binding Path="Something"/>
        <Binding Path="SomethingElse"/>
    </Binding>
</ContentControl.Content>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...