wpf 多重绑定到视图模型?

发布于 2024-08-07 05:16:39 字数 530 浏览 10 评论 0原文

如何向 xaml 中的多个视图模型对象添加多重绑定?

我需要将上下文菜单的 IsEnabled 属性绑定到视图模型中的两个整数。以下绑定不起作用,因为它是为 GUI 组件设计的。我该如何做才能与我的ints一起工作?

<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 对象。

How does one add a multibinding to several viewmodel objects in xaml?

I need to bind the IsEnabled property of a context menu to two integers in my viewmodel. The following binding doesn't work, since its designed for GUI components. How would I do it to work with my ints?

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

MyMenuItem is CLR object with the two integers, FirstInt and SecondInt.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北方的巷 2024-08-14 05:16:39

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

Filip's answer was acceptable, but for anyone looking for Filip's desired solution, the following should do it:

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

It should be noted that the AncestorType on the binding may need to be changed accordingly. I assumed the view model was set as the DataContext of the window, but the same idea applies to user controls, etc.

滥情空心 2024-08-14 05:16:39

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

For your particular example you need an IMultiValueConverter that will convert the two integers to a boolean value representing whether the menu item is enabled or not. Something like this:

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

Used like this:

<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>
通知家属抬走 2024-08-14 05:16:39

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>

Bluebit your wait is over...create a style for your target control instead.

Here is an example where I have a button which is a Login button which needs to be disabled if a combo box (named comboConfig) does not have a selection yet (selected index -1) or if a boolean value on my ViewModel is set to true (LoginInProcess). For the ViewModel boolean I simply set the its path to be the member name property, which is bound at the style time to the 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>
つ可否回来 2024-08-14 05:16:39

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

我认为他问的是如何使用多重绑定,它不绑定到 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();
        }
    }

它不像多重绑定那样干净,因为父对象可能是一个更大的对象,包含更多对象成员,但这对我来说有效。如果我可以使用多重绑定解决方案,我会得到更好看的代码。

This is an old post I know but I have the same problem and couldn't find any solution on the net.

I think what he is asking is how to use a multibinding which doesn't bind to a GUI element instead binds to more than one property in the view model.

Something like this:

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;}}

}

I haven't been able to figure this out either. Instead I used a SingleValueConverter and a binding to a parent object which holds both the variables FirstInt and SecondInt and in the converter use this parent, smth like:

 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();
        }
    }

It's not as clean as if a Multibinding as the parent could be a bigger object with many more members but it worked in my case. I would have better looking code if I could use the Multibinding solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文