【问题标题】:wpf multibinding to viewmodel?wpf多重绑定到viewmodel?
【发布时间】:2010-12-05 21:52:12
【问题描述】:

在我的一生中,我似乎无法使用多重绑定绑定到我的视图模型。网络上的所有示例都直接绑定到 gui 元素,但是每当我尝试使用 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 是具有两个整数 FirstInt 和 SecondInt 的 CLR 对象。

【问题讨论】:

  • 提供更多细节或源代码以重现您的问题

标签: wpf mvvm multibinding


【解决方案1】:

对于您的特定示例,您需要一个 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>

【讨论】:

    【解决方案2】:

    这是我知道的旧帖子,但我有同样的问题,在网上找不到任何解决方案。

    我认为他要问的是如何使用不绑定到 GUI 元素的多重绑定,而是绑定到视图模型中的多个属性。

    类似这样的:

    Xaml:

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

    视图模型:

    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 解决方案,我会有更好看的代码。

    【讨论】:

    • 绑定 Binding 的源会产生运行时异常。
    【解决方案3】:

    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>
    

    【讨论】:

      【解决方案4】:

      Filip 的回答是可以接受的,但对于任何寻找 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,但同样的想法也适用于用户控件等。

      【讨论】:

      • 这应该是被接受的答案。如果它对您不起作用,请尝试将 NotifyOnSourceUpdated="True" 显式添加到两个绑定中。
      猜你喜欢
      • 2011-02-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 2011-07-17
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多