【问题标题】:How to raise the TextChanged of TextBox in Custom Control如何在自定义控件中提高 TextBox 的 TextChanged
【发布时间】:2017-05-12 08:31:24
【问题描述】:

public class CustomSearchControl : Control
    {
        static CustomSearchControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomSearchControl),
                        new FrameworkPropertyMetadata(typeof(CustomSearchControl)));

            CommandManager.RegisterClassCommandBinding(typeof(CustomSearchControl), 
                        new CommandBinding(CustomSearchControl.DeleteCommand, C_DeleteCommand));
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }

        static void C_DeleteCommand(object sender, ExecutedRoutedEventArgs e)
        {
            CustomSearchControl mycontrol = sender as CustomSearchControl;
            mycontrol.SearchText = "";
        }
        public static readonly ICommand DeleteCommand = new RoutedUICommand("DeleteCommand", "DeleteCommand", 
                                    typeof(CustomSearchControl), 
                                            new InputGestureCollection(new InputGesture[] 
                                            { new KeyGesture(Key.Enter), new MouseGesture(MouseAction.LeftClick) }));


        public static readonly DependencyProperty SearchTextProperty =
                    DependencyProperty.Register("SearchText", 
                                                    typeof(string),
                                                    typeof(CustomSearchControl),
                                                    new FrameworkPropertyMetadata(
                                                        null,
                                                        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                                        SearchTextPropertyChanged));
        public string SearchText
        {
            get { return (string)base.GetValue(SearchTextProperty); }
            set { base.SetValue(SearchTextProperty, value); }
        }

        private static void SearchTextPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
        {
            CustomSearchControl mycontrol = d as CustomSearchControl;
            mycontrol.SearchText = e.NewValue.ToString();
        }
    }
<ResourceDictionary x:Class="CustomSearchControl" 
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WpfApplicationCustomSearchControl">
    
    <Style TargetType="{x:Type local:CustomSearchControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CustomSearchControl}">
                    <Grid>
                        <StackPanel Orientation="Horizontal">
                            <TextBox x:Name="tbSearchTextBox"
                                     Width="200" Height="25"
                                     Text="{TemplateBinding SearchText}">
                            </TextBox>
                            <Button x:Name="btnDelete"
                                    Width="50" Height="25"
                                    Content="Delete"
                                    Command="{x:Static local:CustomSearchControl.DeleteCommand}">
                            </Button>
                        </StackPanel>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

<Window...>
  <Grid>
        <local:CustomSearchControl SearchText="{Binding Path=SearchText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
    </Grid>
</Window>

我想创建一个自定义控件,其中包含一个文本框和一个清除文本框的按钮。 如果 TextBox 中的 Text 发生更改,则不会引发 PropertyCallBack。当引发 DeleteCommand 时,也会出现同样的问题。

怎么了?

【问题讨论】:

  • “如果 TextBox 中的文本发生更改,则不会引发 PropertyCallBack” - 不清楚,您能更好地描述问题吗?你的意思是Text="{TemplateBinding SearchText, UpdateSourceTrigger=PropertyChanged}"(见this)?
  • 在 MainWindow 中,CustomControl 的 SearchTextProperty 绑定到 ViewModel 中的公共属性“SearchText”,该属性具有 INotifyPropertyChanged。我的意思是 CustomControl 中的 SearchTextPropertyChanged 方法
  • 为什么需要回调? TemplateBinding 已经更新 TextBox (请参阅@Quarzy 答案)。我理解您的问题,就好像您键入文本并且未调用回调(在绑定将更新源之前不会调用它,因此我对如何输入的评论将在每次更改 Text 后更新)。

标签: c# wpf


【解决方案1】:

我不太明白你想要达到什么目的,但我相信至少有一个错误:你为什么要处理 SearchTextPropertyChanged?

你可以替换:

new FrameworkPropertyMetadata(null,FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,SearchTextPropertyChanged));

new FrameworkPropertyMetadata(default(string));

仅此而已,searchText 能够自行更新。

无论如何,我建议您使用更经典的方法,使用MVVM 创建视图和视图模型,它会更容易实现、测试和维护。

【讨论】:

  • 请注意,使用仅视图使用的依赖属性创建这样的自定义控件是完全可以的。这不需要视图模型。
  • @Quarzy:如果我没有将 customControl 的 SearchTextProperty 绑定到 ViewModel 中的 SearchTextProperty,您的解决方案将有效。我需要绑定到 ViewModelProperty,因为使用 CustomControl 的 TextBox 中的文本,我想在几个不同的 UserControl 中触发 Controls 的 FilterMethods。
  • @Sinatr:我需要更改文本框,因为我必须为包含 CustomControl 的控件实现过滤
  • @Jürgen,您可以保留所有内容,只需删除 mycontrol.SearchText = e.NewValue.ToString()。当SearchText 依赖属性改变时回调被调用,你不应该在回调中再次改变它。
  • @Sinatr:这正是问题所在。如果我将 CustomControl 的 SearchtextProperty 绑定到 StringProperty,例如绑定到 filtermethods 文本的更改不会触发。
【解决方案2】:

好的,我已经找出问题并解决了问题。问题的原因是 Generic.xaml 的 TextBox 中的“TemplatedBinding”。

首先在 Generic.xaml 中进行更改:

&lt;TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=SearchText,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"&gt;

第二个是在 UserControl 中将 Searchtext-Property 绑定到 ViewModel-Property:

&lt;local:CustomSearchControl SearchText="{Binding Path=ViewModelPropertyText,Mode=TwoWay}"/&gt;

现在它工作正常,您可以将 CustomControl 的 SearchText-Property 绑定到您想要的任何内容!

感谢所有考虑过我的问题的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多