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

Bind text to converter based on change in two different objects

我试图根据两件事绑定文本块的文本 -

我想调用转换器,因为我希望文本依赖于 above.The 中任一种值的变化,我唯一能想到的就是这种方式,如下所示。但这是不可能的,因为我无法将 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

的变化调用转换器

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

也就是说,我强烈建议您在 ViewModel 中确定所需的值,因为您已经拥有所有需要的属性,并且您知道它们何时以及如何更改。获得派生 属性 后,只需使用常规绑定在视图中绑定到它。使用 MultiBindings 通常会破坏你的关注点分离,因为你最终会向转换器添加特定的逻辑,而这些逻辑实际上应该在 ViewModel 中。我确实发现 MultiBindings 必不可少的一个案例是在一组 header 模板中(即 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?)中监听 collection 的变化。然后创建一些虚拟 属性,当 collection 更改时,只需增加虚拟 属性(当然使用 INotifyPropertyChanged)并在多重绑定中使用该 属性 作为第三个绑定.这样,如果 属性 发生变化,或者您的列表发生变化,TextBlock 文本将得到更新。

如果您不关心 collection 中的更改,只有当您分配一个全新的 collection 时,所提供的示例才会按原样工作。