wpf multibinding to viewmodel?

时间:2009-10-12 07:44:24

标签: wpf mvvm multibinding

对于我的生活,我似乎无法使用multibindings绑定到我的viewmodel。 net上的所有示例都直接绑定到gui元素,但每当我尝试使用viewmodel对象时,都会抛出异常。

我的问题是,如何在xaml中为多个viewmodel对象添加多重绑定?

我需要将上下文菜单的IsEnabled属性绑定到viewmodel中的两个整数。以下绑定不起作用,因为它是为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。

4 个答案:

答案 0 :(得分:14)

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,但同样的想法适用于用户控件等。

答案 1 :(得分:2)

对于您的特定示例,您需要一个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 :(得分: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解决方案,我会更好看代码。

答案 3 :(得分:1)

Bluebit等待结束了......为目标控件创建一个样式。

这是一个例子,我有一个按钮是一个登录按钮,如果一个组合框(名为comboConfig )还没有选择(选择索引-1)或者需要被禁用如果我的ViewModel上的布尔值设置为true(LoginInProcess)。对于ViewModel布尔值,我只需将其路径设置为成员名称属性,该属性在样式时绑定到windows 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>