8

我正在使用 Infragistics XamDateTimeEditor 控件,我想向它添加一个依赖属性,以允许开发人员选择在控件获得焦点时选择所有文本。我创建了一种样式,用于设置我想要的行为,但我希望开发人员决定是否应该基于布尔依赖属性执行该行为。我不确定那是怎么做的。

4

1 回答 1

18

我假设您为此从 XamDateTimeEditor 继承。

如果您可以编写引用“标准”(clr)属性的代码,那么您就可以开始了:

  1. 声明你的 DependencyProperty
  2. 删除您的支持字段并替换标准属性的实现,以便它访问 DependencyProperty 而不是支持字段。

    public class MyXamDateTimeEditor : XamDateTimeEditor
    {
        public static readonly DependencyProperty IsSelectOnFocusEnabledProperty = 
          DependencyProperty.Register("IsSelectOnFocusEnabled", typeof(bool), 
        typeof(MyXamDateTimeEditor), new UIPropertyMetadata(false));
    
        public boolIsSelectOnFocusEnabled
        {
            get
            {
                return (bool)GetValue(IsSelectOnFocusEnabledProperty);
            }
            set
            {
                SetValue(IsSelectOnFocusEnabledProperty, value);
            }
        }
    }
    

然后,当您在代码中访问 IsSelectOnFocusEnabled 时,它将返回依赖属性的当前值。

您也可以将其设置为在属性更改时接收通知,但我不明白您为什么会这样。

此技巧还有另一种选择,如果您愿意,它不使用继承和附加属性。

更新:

好的,因为它被要求,这里有一种方法可以为任何文本框实现它。它应该很容易转换为您用来在另一种类型的控件上执行该操作的任何事件。

    public class TextBoxBehaviors
    {
        public static bool GetIsSelectOnFocusEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsSelectOnFocusEnabledProperty);
        }

        public static void SetIsSelectOnFocusEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsSelectOnFocusEnabledProperty, value);
        }

        public static readonly DependencyProperty IsSelectOnFocusEnabledProperty =
            DependencyProperty.RegisterAttached("IsSelectOnFocusEnabled", typeof(bool), 
            typeof(TextBoxBehaviors), 
            new UIPropertyMetadata(false, new PropertyChangedCallback(OnSelectOnFocusChange)));

        private static void OnSelectOnFocusChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TextBox)
            {
                var tb = d as TextBox;
                if ((bool)e.NewValue)
                {
                    tb.GotFocus += new RoutedEventHandler(tb_GotFocus);
                }
                else
                {
                    tb.GotFocus -= new RoutedEventHandler(tb_GotFocus);
                }
            }
        }

        static void tb_GotFocus(object sender, RoutedEventArgs e)
        {
            var tb = sender as TextBox;

            tb.SelectAll();
        }

    }

你使用它的方式如下,例如:

<Window x:Class="WpfApplication2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"        
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBox Text="No Select All" x:Name="TextBox1"/>
        <CheckBox Content="Auto Select"
                  Grid.Column="1"
                  IsChecked="{Binding Path=(local:TextBoxBehaviors.IsSelectOnFocusEnabled), ElementName=TextBox1, Mode=TwoWay}" />
        <TextBox Grid.Row="1" Text="djkhfskhfkdssdkj"
                 local:TextBoxBehaviors.IsSelectOnFocusEnabled="true" />
    </Grid>
</Window>

这向您展示了如何设置属性以激活行为,以及如何在需要时将其绑定到其他东西。请注意,这个特定示例并不完美(如果您通过它工作,如果您在控件内部单击,则文本框具有实际上取消选择文本的内部逻辑,但这只是关于如何通过附加属性将行为附加到控件的示例) .

于 2009-05-02T23:46:36.180 回答