wpf multibinding к viewmodel? - PullRequest
       18

wpf multibinding к viewmodel?

4 голосов
/ 12 октября 2009

Насколько я могу судить, я не могу связываться с моей моделью представления, используя мультипривязки. Все примеры в сети напрямую связаны с элементами gui, но всякий раз, когда я пытаюсь использовать объект viewmodel, генерируются исключения.

У меня вопрос: как добавить мультисвязывание к нескольким объектам модели представления в xaml?

Мне нужно привязать свойство IsEnabled контекстного меню к двум целым числам в моей модели представления. Следующая привязка не работает, так как она предназначена для компонентов GUI. Как бы я сделал это, чтобы работать с моими int?

<MenuItem ItemsSource="{Binding MyMenuItem}">
    <MenuItem.IsEnabled>
        <MultiBinding>
            <Binding ElementName="FirstInt" Path="Value" />
            <Binding ElementName="SecondInt" Path="Value" />
        </MultiBinding>
    </MenuItem.IsEnabled>
</MenuItem>

MyMenuItem - объект CLR с двумя целыми числами, FirstInt и SecondInt.

Ответы [ 4 ]

15 голосов
/ 13 июня 2014

Ответ Филипа был приемлемым, но для любого, кто ищет желаемое решение Филипа, это должно сделать следующее:

<MenuItem ItemsSource="{Binding MyMenuItem}">
    <MenuItem.IsEnabled>
        <MultiBinding  Converter="{StaticResource IntsToEnabledConverter}">
            <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Window}" Path="DataContext.FirstInt" />
            <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Window}" Path="DataContext.SecondInt" />
        </MultiBinding>
    </MenuItem.IsEnabled>
</MenuItem>

Следует отметить, что AncestorType на привязке может потребоваться изменить соответствующим образом. Я предположил, что модель представления была установлена ​​как DataContext окна, но та же идея применима к пользовательским элементам управления и т. Д.

2 голосов
/ 12 октября 2009

Для вашего конкретного примера вам нужен IMultiValueConverter, который преобразует два целых числа в логическое значение, представляющее, включен ли пункт меню или нет. Примерно так:

Public Class MVCIntsToEnabled
    Implements IMultiValueConverter

    Public Function Convert(ByVal values() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert
        If values IsNot Nothing Then
            If values.Count = 2 Then
                Return (values(0) > 0) AndAlso (values(1) > 0)
            Else
                Return False
            End If
        Else
            Throw New ArgumentNullException("values")
        End If
    End Function

    Public Function ConvertBack(ByVal value As Object, ByVal targetTypes() As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function

End Class

Используется так:

<local:MVCIntsToEnabled x:Key="IntsToEnabledConverter"  />

...

<MenuItem ItemsSource="{Binding MyMenuItem}">
    <MenuItem.IsEnabled>
        <MultiBinding  Converter="{StaticResource IntsToEnabledConverter}">
            <Binding ElementName="FirstInt" Path="Value" />
            <Binding ElementName="SecondInt" Path="Value" />
        </MultiBinding>
    </MenuItem.IsEnabled>
</MenuItem>
1 голос
/ 15 января 2013

Bluebit, ваше ожидание закончено ... вместо этого создайте стиль для целевого элемента управления.

Вот пример, где у меня есть кнопка, которая является кнопкой входа в систему, которую необходимо отключить, если в поле со списком ( с именем comboConfig ) еще нет выбора (выбранный индекс -1) или если логическое значение в моей ViewModel установлено в true (LoginInProcess). Для логического представления ViewModel я просто установил его путь в качестве свойства имени элемента, которое во время стиля привязано к тексту данных Windows:

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Style.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource MultiComboBoolBoolFalse}">
                    <Binding ElementName="comboConfig" Path="SelectedIndex" />
                    <Binding Path="LoginInProcess"/>
                </MultiBinding>
            </DataTrigger.Binding>
            <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
1 голос
/ 05 октября 2010

Это старый пост, который я знаю, но у меня та же проблема, и я не смог найти решения в сети.

Я думаю, что он спрашивает, как использовать мультисвязывание, которое не привязывается к элементу GUI, а связывается с более чем одним свойством в модели представления.

Примерно так:

Xaml:

<MenuItem ItemsSource="{Binding MyMenuItem}">
    <MenuItem.IsEnabled>
        <MultiBinding  Converter="{StaticResource IntsToEnabledConverter}">
            <Binding Source="{Binding FirstInt}" />
            <Binding Source="{Binding SecondInt}" />
        </MultiBinding>
    </MenuItem.IsEnabled>
</MenuItem>

ViewModel:

public class ViewModel
{
 public int FirstInt{ get { return _firstInt;}}
 public int SecondInt{ get { return _secondInt;}}

}

Я тоже не смог этого понять. Вместо этого я использовал SingleValueConverter и привязку к родительскому объекту, который содержит обе переменные FirstInt и SecondInt, а в конвертере используется этот родительский элемент, что-то вроде:

 public class IntsToEnabledConverter :IValueConverter 
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Parent parent = value as Parent;

            if (parent.FirstInt == 1 && parent.SecondInt == 1)
                return true;
            else
                return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

Он не такой чистый, как если бы Multibinding, как родитель, мог бы быть большим объектом с большим количеством членов, но в моем случае это сработало. Я бы лучше посмотрел код, если бы мог использовать решение Multibinding.

...