【问题标题】:Philosophy on Binding to Parameters in WPFWPF中参数绑定的哲学
【发布时间】:2014-04-26 19:07:33
【问题描述】:

所以我正在尝试构建一个项目,该项目将允许用户在表单左侧的文本框中键入一些文本,并从我的数据源列表中过滤掉可用的项目。

<Label Content="Enter item name below"></Label>
<TextBox Name="SearchTermTextBox" TabIndex="0" Text="" />

我的印象是我可以将列表绑定到数据源,然后使用转换器过滤掉与字符串不同的项目。

<ListBox DataContext="{Binding Colors}">
   <ListBox.ItemsSource>
     <MultiBinding Converter="{StaticResource FilterTextValueConverter}" ConverterParameter="{Binding ElementName=SearchTermTextBox, Path=Text}" />
   </ListBox.ItemsSource>
   <ListBox.ItemTemplate>
       //etc...
    </ListBox.ItemTemplate>
</ListBox>

但是,除非您使用称为依赖属性的东西,否则您不能绑定到转换器参数中的元素名称。

编辑:看到我对上面的代码造成了混淆,这是我要绑定的转换器:

public class FilterTextValueConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var trackedColors = value as List<Colors>;
        if (trackedColors != null)
            return (trackedColors).Where(item => item.ColorName.Contains(parameter.ToString())).ToList();

        return null;
    }

    public object ConvertBack(object value, Type targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


public class Colors
{
    public String ColorName;
    public String Description;
}

我的方法有什么问题?显然,我激怒了 WPF 众神,因为这是一个相当简单的操作,但原则上我被拒绝了。任何帮助将不胜感激。

【问题讨论】:

    标签: c# wpf binding valueconverter


    【解决方案1】:

    使用转换器的简单绑定在这里可以工作,不需要 MultiBinding。

    <ListBox ItemsSource="{Binding Path=Text, ElementName=SearchTermTextBox,
                              Converter="{StaticResource FilterTextValueConverter}">
       ......
    </ListBox>
    

    假设 FilterTextValueConverter 正在实现 IValueConverter,您可以从传递给 Convert 方法的值访问文本。

    public class FilterTextValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, 
                              System.Globalization.CultureInfo culture)
        {
            string text = value.ToString(); // TEXT for textBox can be accessed here.
            return new List<string>(); // Return filtered list from here.
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, 
                                  System.Globalization.CultureInfo culture)
        {
            return Binding.DoNothing;
        }
    }
    

    更新

    如果您想将多个绑定传递给转换器,请使用 IMultiValueConverter,因为 ConverterParameter 不是 Dependency 属性,因此无法绑定。

    XAML

    <ListBox DataContext="{Binding Colors}">
        <ListBox.ItemsSource>
            <MultiBinding Converter="{StaticResource FilterTextValueConverter}">
                <Binding/>
                <Binding ElementName="SearchTermTextBox" Path="Text"/>
            </MultiBinding>
        </ListBox.ItemsSource>
    </ListBox>
    

    转换器

    public class FilterTextValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, 
                              System.Globalization.CultureInfo culture)
        {
            var trackedColors = values[0] as List<Colors>;
            if (trackedColors != null && !String.IsNullOrEmpty(values[1].ToString()))
                return (trackedColors).Where(item => 
                       item.ColorName.Contains(values[1].ToString())).ToList();
    
            return null;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes,
                                    object parameter,
                                    System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 不幸的是,我需要将 ConverterParameter 绑定到 SearchTermTextBox,而 Visual Studio 不允许这样做。我的转换器必须返回 List.
    • 我已经编辑了原件以更好地解释我的情况。我同意 multi 是不必要的,这只是一个实验。
    • 转换器参数无法绑定。您需要使用IMultiValueConverter。我已经更新了答案。看看有没有帮助。
    • 我昨晚碰巧登陆了这个,但我会把你标记为答案。虽然我仍然不明白为什么我们不允许绑定到转换器参数。
    • 我只是将您提供的代码置于问题中。我更新的任何方式。关于Though I still don't understand why we're not allowed to bind to converterparameter. - 因为 WPF 家伙将 ConverterParameter 设为普通 CLR 属性而不是 DP(绑定支持仅适用于 DP)。不知道他们为什么这样做。
    【解决方案2】:

    在接受的答案发布并为我工作后,我继续研究这个问题。我发现,包装你试图从中获取新依赖属性以允许正确绑定的控件是一项相当简单的任务。

    我不会接受我自己的答案这么晚才确定,但这似乎(在我的业余爱好者看来)是一个比添加转换器更优雅的解决方案,尽管有点复杂:

    请注意,这是针对文本框的 caretindex 属性的新依赖,而不是针对绑定的原始问题,但它只需要一些智能重命名即可使其正常工作;)。

        public class TextBoxDependencyWrapper : TextBox
        {
            public static readonly DependencyProperty CaretIndexProperty = DependencyProperty.Register(
                "CaretIndex", typeof (int), typeof (TextBoxDependencyWrapper), new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, CaretIndexChanged ));
    
            protected override void OnKeyUp(KeyEventArgs e) //Event that changes the property we're trying to track
            {
                base.OnKeyUp(e);
                CaretIndex = base.CaretIndex;
            }
    
            protected override void OnKeyDown(KeyEventArgs e) //Event that changes the property we're trying to track
            {
                base.OnKeyDown(e);
                CaretIndex = base.CaretIndex;
            }
    
            public new int CaretIndex
            {
                get { return (int) GetValue(CaretIndexProperty); }
                set { SetValue(CaretIndexProperty, value); }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-17
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多