WPF难以绑定:将值绑定到IConverter,并将静态方法的结果作为输入

本文关键字:绑定 结果 静态方法 输入 IConverter WPF | 更新日期: 2023-09-27 18:03:49

我想知道是否有可能有以下类型的绑定,我无法形成一个搜索查询,给我明确的答案,或在任何地方找到它。

情况是这样的。

我有一个ListBox 'Items'(一个自定义类),这些项目使用项目模板显示。我使用一个转换器来计算背景颜色。见下文:

<Window.Resources>
    <local:MyConverter x:Key="myConverter"/>
</Window.Resources>
<!-- snip -->
<ListBox Grid.Row="2" Name="listBoxMaterialType" Margin="0,0,0,0" ItemsSource="{Binding Path=MyItems, ElementName=MySource}">
    <ListBox.ItemTemplate>
        <DataTemplate>
                <TextBlock Text="{Binding DisplayText}" Background="{Binding Converter={StaticResource myConverter}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

现在为了更好的抽象,我希望MyConverter不转换Item,而只转换Item的分数。一个项目不知道它自己的分数,但是分数是通过调用MyStaticClass.MyStaticMethod(item)来计算的;在代码中,我想这样做一个绑定:myTextBlock。背景= MyConverter (MyStaticClass.MyStaticMethod(项);有可能在WPF中使用数据绑定做到这一点吗?

WPF难以绑定:将值绑定到IConverter,并将静态方法的结果作为输入

传统上,ViewModel的角色是获取域对象并公开视图所需的数据。这可以包括添加新属性,这些属性是模型属性的聚合或转换(例如,通过连接FirstName和姓氏模型属性来提供FullName属性)。在你的例子中:

public class Item
{
    public string DisplayText { get; set; }
}
public class ItemViewModel
{
    private Item _model;
    public string DisplayText
    {
        get { return _model.DisplayText; }
    }
    public int Score
    {
        get { return MyStaticClass.MyStaticMethod(_model);
    }
}

然后,使用ViewModel作为DataContext,您可以将转换器直接绑定到Score属性。

你可以做很多事情,例如,你可以添加一些属性到你的转换器指向一个方法。比如TargetType TargetObject &MethodName,然后您可以-通过指定MethodName和其他任何属性-使转换器调用TargetObject或静态的方法。

。像这样:

//<Property declarations>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    bool staticCall = TargetObject == null;
    var types = new Type[] { value.GetType() };
    var args = new object[] { value };
    MethodInfo method;
    if (staticCall)
    {
        method = TargetType.GetMethod(MethodName, types);
    }
    else
    {
        method = TargetObject.GetType().GetMethod(MethodName, types);
    }
    var score = method.Invoke(TargetObject, args);
    //Convert score
}

(与所有粗略的片段一样,不要盲目地复制粘贴,这可能很糟糕)

<vc:MyConverter x:Key="ScoreConverter"
                TargetType="{x:Type local:MyStaticClass}"
                MethodName="MyStaticMethod"/>

当然,转换器通过应用您所描述的静态函数来完成它的工作:从一项到一种颜色。一切顺利。

如果你考虑到分数的颜色可能在某些条件下改变,问题就出现了。您认为可以通过哪种方式触发绑定来更新颜色值(从而调用转换器)?

我想这更多的是一个结构问题而不是技术问题。

编辑:要么我不理解这个问题,要么解决方案很简单:

    public class MyConverter
        : IValueConverter
    {
        public object Convert(
            object value, 
            Type targetType, 
            object parameter, 
            System.Globalization.CultureInfo culture)
        {
            return MyStaticClass.MyStaticMethod(value as MyItem);
        }
        public object ConvertBack(
            object value, 
            Type targetType, 
            object parameter, 
            System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

我也会在绑定子句中添加Mode=OneTime。

欢呼