2009-10-12 3 views
4

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

Мой вопрос: как добавить многосвязывание к нескольким объектам viewmodel в xaml?

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

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

+3

Что вы думаете? – Natrium

+1

дайте более подробную информацию или исходный код для воспроизведения вашей проблемы. – japf

ответ

3

Для вашего конкретного примера вам нужен 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> 
3

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

Я думаю, что он спрашивает, как использовать многосвязывание, которое не привязывается к элементу 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.

+0

Привязка источника привязки дает исключение во время выполнения. – Brannon

1

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

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

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

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

<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 окна, но та же идея относится к пользовательским элементам управления и т. Д.

+0

Это должен быть принятый ответ. Если это не сработает для вас, попробуйте явно добавить 'NotifyOnSourceUpdated =" True "' для обеих привязок. – Artholl

Смежные вопросы