给控件添加依赖属性

8

我正在使用Infragistics XamDateTimeEditor控件,想要为其添加一个依赖属性,使开发人员可以选择在控件获取焦点时选择所有文本。 我已经创建了一个样式来设置所需的行为,但我希望开发人员可以根据布尔依赖属性决定是否执行该行为。 我不确定如何完成这个操作。

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时,它将返回Dependency Property的当前值。
您还可以设置它以接收属性更改的通知,但在您的情况下我不明白为什么要这样做。
如果您想要,还有另一种没有继承和使用附加属性的选项来实现此技巧。
更新:
好的,既然被请求了,这里有一个适用于任何文本框的方法。对于在其他类型的控件上执行此操作所使用的任何事件,都应该很容易进行转换。
    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>

本示例展示了如何设置属性以激活某种行为,并在需要时将其绑定到其他内容。请注意,此特定示例并不完美(如果您通过Tab键进行操作,则可以正常工作;如果您单击控件内部,则文本框具有实际取消选择文本的内部逻辑,但这只是演示如何通过附加属性将行为附加到控件的示例)。


1
如果XamDateTimeEditor没有扩展DependencyObject,那么代码将无法编译。例如,我正在扩展一个行为,并希望向其添加一个依赖属性,但我无法这样做。 - rollsch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接