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

时间:2018-04-07 00:53:14

标签: c# wpf xaml multibinding converters

我试图基于两件事来绑定文本块的文本 -

  • 对象 ShoppingList
  • Object Items (这是 ShoppingList 对象的属性。 Type是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;
}

简单来说,如何根据 Items ShoppingList

中的更改来调用转换器

1 个答案:

答案 0 :(得分:0)

听起来像是在寻找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 1}}接口see here。但这还不够,因为绑定不会订阅该事件。您需要在DataContext(ViewModel?)中收听集合中的更改。然后创建一些虚拟属性,当集合发生更改时,只需递增虚拟属性(当然使用INotifyPropertyChanged)并将多绑定中的该属性用作第三个绑定。这样,如果属性更改或列表更改,TextBlock文本将会更新。

如果您不关心集合中的更改,只有在分配了整个新集合时,所提供的示例才能正常工作。