WPF:自定义创建的用户控件中的数据绑定

某人

我创建了自己的 WPF 用户控件,这是一个带有自动完成建议的文本框。XAML 看起来像这样:

<UserControl x:Class="WpfApplication4.AutoCompleteTextBox"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfApplication4"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Vertical">
    <TextBox x:Name="textBox" />
    <ListBox x:Name="listBox" MaxHeight="100"/>
</StackPanel>

后面的代码是这样的:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApplication4
{
/// <summary>
/// A WPF component which has a textbox. If the user enters some text, a ListBox is displayed showing some suggestions which the user can follow or not.
/// </summary>
public partial class AutoCompleteTextBox : UserControl
{

    /// <summary>
    /// This event is invoked when the text of the textbox is changed.
    /// </summary>
    public event TextChangedEventHandler TextChanged;

    /// <summary>
    /// Needed for DataBinding of Suggestions
    /// </summary>
    public static DependencyProperty SuggestionsProperty;

    /// <summary>
    /// Needed for data binding of Text
    /// </summary>
    public static DependencyProperty TextProperty;

    /// <summary>
    /// A list of the suggestions which are displayed to the user.
    /// </summary>
    public List<string> Suggestions { get
        {
            return (List<string>) GetValue(SuggestionsProperty);
        }
        set
        {
            SetValue(SuggestionsProperty, value);
        }

    }

    /// <summary>
    /// True if showing of the suggestions is case-sensitive; false, if case-insensitive
    /// </summary>
    public bool CaseSensitive { get; set; }

    /// <summary>
    /// The text displayed inside the textbox
    /// </summary>
    public string Text
    {
        get
        {
            return textBox.Text;
            //return (string)GetValue(TextProperty);
        }
        set
        {
            SetValue(TextProperty, value);
            textBox.Text = value;
        }
    }

    /// <summary>
    /// Create a new AutoCompleteTextBox
    /// </summary>
    public AutoCompleteTextBox()
    {
        InitializeComponent();
        Suggestions = new List<string>();
        DataContext = this;
        listBox.Visibility = Visibility.Collapsed;
        CaseSensitive = true;
        textBox.TextChanged += ExternalTextEvent;
        textBox.TextChanged += textChanged;
        textBox.PreviewKeyDown += keyDown;
        textBox.LostFocus += lostFocus;
        textBox.GotFocus += gotFocus;
        listBox.SelectionChanged += selectionChanged;
    }

    private void ExternalTextEvent(object sender, TextChangedEventArgs e)
    {
        TextChanged?.Invoke(this, e);
    }

    static AutoCompleteTextBox()
    {
        SuggestionsProperty = DependencyProperty.Register(nameof(Suggestions), typeof(List<string>), typeof(AutoCompleteTextBox));
        TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(AutoCompleteTextBox));
    }

    private void gotFocus(object sender, RoutedEventArgs e)
    {
        updateListBox();
    }

    private void lostFocus(object sender, RoutedEventArgs e)
    {
        listBox.Visibility = Visibility.Collapsed;
    }

    private void keyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter || e.Key == Key.Return)
        {
            if (listBox.Visibility == Visibility.Visible)
            {
                listBox.Visibility = Visibility.Collapsed;
                textBox.TextChanged -= textChanged;
                textBox.Text = (string)listBox.Items[0];
                textBox.TextChanged += textChanged;
            }
        }
        if (e.Key == Key.Escape)
        {
            listBox.Visibility = Visibility.Collapsed;
        }
        //if(e.Key == Key.Down && listBox.Visibility == Visibility.Visible)
        //{
        //    textBox.LostFocus -= lostFocus;
        //    listBox.SelectedIndex = 0;
        //    textBox.LostFocus += lostFocus;
        //}
    }

    private void selectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (listBox.ItemsSource != null)
        {
            listBox.Visibility = Visibility.Collapsed;
            textBox.TextChanged -= textChanged;
            if (listBox.SelectedIndex != -1)
            {
                textBox.Text = listBox.SelectedItem.ToString();
            }
            textBox.TextChanged += textChanged;
        }
    }

    private void textChanged(object sender, TextChangedEventArgs e)
    {
        SetValue(TextProperty, textBox.Text);
        updateListBox();
    }

    private void updateListBox()
    {
        if (String.IsNullOrEmpty(textBox.Text) || Suggestions == null || Suggestions.Count == 0)
        {
            return;
        }
        List<string> autoList = new List<string>();
        foreach (string item in Suggestions)
        {
            if (CaseSensitive && item.StartsWith(textBox.Text))
            {
                autoList.Add(item);
            }
            if (!CaseSensitive && item.ToUpper().StartsWith(textBox.Text.ToUpper()))
            {
                autoList.Add(item);
            }
        }
        if (autoList.Count > 0)
        {
            listBox.ItemsSource = autoList;
            listBox.Visibility = Visibility.Visible;
        }
        else
        {
            listBox.Visibility = Visibility.Collapsed;
            listBox.ItemsSource = null;
        }
    }
}
}

如果我使用这个用户控件,例如

<local:AutoCompleteTextBox x:Name="autocomplete" Suggestions="{Binding SomeList}" Text="{Binding SomeText,UpdateSourceTrigger=PropertyChanged}"/>

那么数据绑定对于建议列表非常有效,但它不适用于文本框的文本。我不知道我做错了什么。有人可以帮忙吗?我会很感激。

毫米8

依赖属性的 CLR 包装器的 getter 和 setter 应该调用GetValueSetValue方法。如果您想在设置属性时进行其他任何操作,则应该使用回调。

您可能还应该将Text属性的默认绑定模式设置TwoWay

public string Text
{
    get
    {
        return (string)GetValue(TextProperty);
    }
    set
    {
        SetValue(TextProperty, value);
    }
}

static AutoCompleteTextBox()
{
    SuggestionsProperty = DependencyProperty.Register(nameof(Suggestions), typeof(List<string>), typeof(AutoCompleteTextBox));
    TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(AutoCompleteTextBox),
        new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnTextChanged)) { BindsTwoWayByDefault = true });
}

private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    AutoCompleteTextBox ctrl = d as AutoCompleteTextBox;
    ctrl.textBox.Text = e.NewValue as string;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

自定义控件数据绑定wpf

来自分类Dev

自定义用户控件不绑定数据

来自分类Dev

绑定到子自定义控件的控件模板中父用户控件代码中定义的属性

来自分类Dev

绑定到子自定义控件的控件模板中父用户控件代码中定义的属性

来自分类Dev

WPF自定义控件-绑定到在后台代码中定义的命令

来自分类Dev

用户控件中的自定义方法

来自分类Dev

用户控件中的自定义事件

来自分类Dev

使用自定义用户控件进行多阶段数据绑定

来自分类Dev

使用WPF C#中的多个控件的组合创建一个自定义控件

来自分类Dev

WPF自定义控件:将CollectionViewSource绑定到DependencyProperty

来自分类Dev

无法绑定自定义控件内容(WPF)

来自分类Dev

在Xamarin中创建自定义控件

来自分类Dev

WPF自定义控件依赖项属性中未知对象的双向绑定问题

来自分类Dev

将ItemsControl中的viewmodel绑定到自定义用户控件

来自分类Dev

WPF 数据绑定用户控件

来自分类Dev

最佳WPF面板可创建自定义控件

来自分类Dev

在 C# 中创建从 WPF 控件派生的自定义 <Page> 类?

来自分类Dev

如何在自定义WPF控件(如折线图)中呈现动态数据?

来自分类Dev

如何在自定义WPF控件(如折线图)中呈现动态数据?

来自分类Dev

WPF双向数据绑定到可观察集合中的自定义数据类型

来自分类Dev

WPF中的自定义控件模板的Click事件

来自分类Dev

WPF自定义控件中的依赖关系

来自分类Dev

WPF:如何使自定义控件中的文本显示?

来自分类Dev

WPF-更新自定义控件中的值

来自分类Dev

在WPF MaterialDesign中悬停自定义控件

来自分类Dev

WPF KeyBinding 命令未在自定义控件中触发

来自分类Dev

根据停靠在其中的webBrowser控件中的数据调整自定义用户控件的大小

来自分类Dev

使用ObservableCollection的自定义控件绑定

来自分类Dev

MVVMCross自定义控件和绑定

Related 相关文章

  1. 1

    自定义控件数据绑定wpf

  2. 2

    自定义用户控件不绑定数据

  3. 3

    绑定到子自定义控件的控件模板中父用户控件代码中定义的属性

  4. 4

    绑定到子自定义控件的控件模板中父用户控件代码中定义的属性

  5. 5

    WPF自定义控件-绑定到在后台代码中定义的命令

  6. 6

    用户控件中的自定义方法

  7. 7

    用户控件中的自定义事件

  8. 8

    使用自定义用户控件进行多阶段数据绑定

  9. 9

    使用WPF C#中的多个控件的组合创建一个自定义控件

  10. 10

    WPF自定义控件:将CollectionViewSource绑定到DependencyProperty

  11. 11

    无法绑定自定义控件内容(WPF)

  12. 12

    在Xamarin中创建自定义控件

  13. 13

    WPF自定义控件依赖项属性中未知对象的双向绑定问题

  14. 14

    将ItemsControl中的viewmodel绑定到自定义用户控件

  15. 15

    WPF 数据绑定用户控件

  16. 16

    最佳WPF面板可创建自定义控件

  17. 17

    在 C# 中创建从 WPF 控件派生的自定义 <Page> 类?

  18. 18

    如何在自定义WPF控件(如折线图)中呈现动态数据?

  19. 19

    如何在自定义WPF控件(如折线图)中呈现动态数据?

  20. 20

    WPF双向数据绑定到可观察集合中的自定义数据类型

  21. 21

    WPF中的自定义控件模板的Click事件

  22. 22

    WPF自定义控件中的依赖关系

  23. 23

    WPF:如何使自定义控件中的文本显示?

  24. 24

    WPF-更新自定义控件中的值

  25. 25

    在WPF MaterialDesign中悬停自定义控件

  26. 26

    WPF KeyBinding 命令未在自定义控件中触发

  27. 27

    根据停靠在其中的webBrowser控件中的数据调整自定义用户控件的大小

  28. 28

    使用ObservableCollection的自定义控件绑定

  29. 29

    MVVMCross自定义控件和绑定

热门标签

归档