根据两个不同对象的变化将文本绑定到转换器[重复]

Posted

技术标签:

【中文标题】根据两个不同对象的变化将文本绑定到转换器[重复]【英文标题】:Bind text to converter based on change in two different objects [duplicate] 【发布时间】:2018-09-17 01:42:20 【问题描述】:

我正在尝试基于两件事绑定文本块的文本 -

对象购物清单 对象Items(它是ShoppingList对象的一个​​属性。类型是List)。

我想调用转换器,因为我希望文本依赖于上述任何一个值的变化。我能想到的唯一方法是这种方式,如下所示。但这是不可能的,因为我无法将 ConverterParameter 绑定到对象 ShoppingList,因为它不是依赖属性。

  <TextBlock
           Margin="5"
           TextWrapping="Wrap"
           Text="Binding Items, Converter=StaticResource ABCDConverter, ConverterParameter="???" />

下面是我写的转换器

Convert(Items obj, object par, xyz culture)

      if (obj != null && par!=null)
      
            var parameter = (ShoppingList)par;
            // Different Logic to determine the string to be returned
      
   return string.Empty;

简单来说,我如何根据 ItemsShoppingList

的变化调用转换器

【问题讨论】:

【参考方案1】:

听起来您正在寻找MultiBinding,并与IMultiValueConverter 配对。

话虽如此,我强烈建议您在 ViewModel 中确定所需的值,因为您已经拥有所有需要的属性,并且您知道它们何时以及如何更改。获得派生属性后,只需使用常规绑定在视图中绑定到它。使用 MultiBindings 通常会破坏您的关注点分离,因为您最终会将特定逻辑添加到真正应该在 ViewModel 中的转换器中。我确实发现 MultiBindings 不可或缺的一个案例是在组标题模板中(即对于 DataGrid)。从 ViewModel 获取值是非常不可能的,因为您不知道您有多少组或它们在运行时将包含什么,因为移动部件太多。在这种情况下,MultiBindings 很棒。 另一方面,如果您只是针对您在设计时了解的特定元素,则通常应避免使用 MultiBinding 出于上述原因。此外,与常规绑定相比,MutliBinding 相当冗长,使您的 XAML 更难阅读,从而产生更大的潜在错误并限制未来的可扩展性和可维护性。

但如果必须,这里有一个简单的例子:

XAML

<Window x:Class="testapp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:testapp"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:MyMultiConverter x:Key="multiTextConverter"/>
    </Window.Resources>

    <Grid>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="StaticResource multiTextConverter">
                    <Binding Path="someProp"/>
                    <Binding Path="someOtherProp" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </Grid>
</Window>

转换器

public class MyMultiConverter : IMultiValueConverter

    public object Convert(object[] values, Type targetType, 
            object parameter, CultureInfo culture)
    
        string ret = null;
        if(values.Count() > 1)
        
            string value1 = values[0] as string;
            string value2 = values[1] as string;
            ret = value1 + value2;
        
        return ret;
    

    public object[] ConvertBack(object value, Type[] targetTypes, 
            object parameter, CultureInfo culture)
    
    

现在,如果您要绑定到List,并且假设您关心何时添加或删除项目,您将需要使用ObservableCollection,因为它实现了INotifyCollectionChanged 接口see here。但这还不够,因为绑定不会订阅该事件。您将需要在 DataContext(ViewModel?)中收听集合的变化。然后创建一些虚拟属性,当集合更改时,只需增加虚拟属性(当然使用 INotifyPropertyChanged)并在多重绑定中使用该属性作为第三个绑定。这样,TextBlock 文本将在属性更改或您的列表更改时得到更新。

如果您不关心集合中的变化,只有当您分配一个全新的集合时,提供的示例才会按原样工作。

【讨论】:

谢谢。显式绑定到两个特定属性有效。此外,关于如何将多重绑定用于 ToolTipContentTemplateSelector 控件的任何想法?基本上,除了文本之外,还有一个我想要的图标和工具提示更改。我在 ContentControl 中有这两个控件,在文本 Block.Something 中有主 qstn 的文本。像这样:&lt;Grid&gt; &lt;Grid Definitions&gt; &lt;Content Control&gt; // containing the contentTempateSelector and tooltip that binds to two resp converters. &lt;TextBlock&gt; //actual qstn txt &lt;Grid&gt; 我想我无法在评论中回答这个问题。考虑只发布另一个问题。也就是说,我个人发现MultiBinding 的用途非常有限。我强烈建议您在 ViewModel 中确定所需的值,因为您已经拥有所有需要的属性,并且只需使用常规绑定来绑定它。使用 MultiBindings 通常会破坏您的关注点分离,因为您最终会将逻辑添加到真正应该在 ViewModel 中的转换器中。 我确实发现 MultiBindings 不可或缺的一个案例是在组标题中(即对于 DataGrid)。从 ViewModel 获取值是非常不可能的,因为您不知道您有多少组或它们包含什么,因为它太动态并且有太多移动部件。在这种情况下,MultiBindings 很棒。另一方面,如果您只是针对您在设计时了解的特定元素,则应避免使用 MultiBinding 出于上述原因。

以上是关于根据两个不同对象的变化将文本绑定到转换器[重复]的主要内容,如果未能解决你的问题,请参考以下文章

将属性绑定到两个不同的控件[重复]

绑定到静态类属性[重复]

以 Z 方式将元素绑定到 2 个不同的列

单向绑定

WPF将单个文本框绑定到集合对象或数组中的元素

具有相同时区信息的两个python日期时间对象的打印方式不同[重复]