简体   繁体   English

如何通过两种方式将Parent UIElement绑定到附加属性?

[英]How do I two way bind a Parent UIElement to an attached property?

I'm developing an on screen keyboard for use in a kiosk style application. 我正在开发用于信息亭样式应用程序的屏幕键盘。 I'm building it in such a way that I wish my on screen keyboard to display a preview of whatever text the user is entering using the keyboard. 我以一种希望我的屏幕键盘显示用户使用键盘输入的任何文本的预览的方式构建它。

In xaml I wish to add an attached property to input field controls within my application, for example a TextBox or ComboBox. 在xaml中,我希望将附加属性添加到应用程序中的输入字段控件,例如TextBox或ComboBox。 I want the preview control on my OnScreenKeyboard to be bound to the same value that the underlying control it is attached to is. 我希望将OnScreenKeyboard上的预览控件绑定到与其附加到的基础控件相同的值。 So if a user clicks on a TextBox, the preview on the on screen keyboard is also a TextBox and is also bound to the same underlying value as the TextBox, eg TextBox.Text. 因此,如果用户单击TextBox,则屏幕键盘上的预览也是TextBox,并且也绑定到与TextBox相同的基础值,例如TextBox.Text。

屏幕键盘

The image I've provided above is how my keyboard will look. 我上面提供的图像是键盘的外观。 Because the keyboard itself is a popup at a fixed position, (Bottom center of the screen) the keyboard may cover the input control (TextBox, PasswordBox, ComboBox, RichTextBox etc...) that a user has clicked on to summon the keyboard, hence the requirement for the preview as part of the keyboard. 由于键盘本身是固定位置的弹出式窗口,(屏幕的底部中央)键盘可能会覆盖用户单击以召唤键盘的输入控件(TextBox,PasswordBox,ComboBox,RichTextBox等...),因此,预览需要作为键盘的一部分。

I know that in xaml I can create an attached property such as 我知道在xaml中我可以创建一个附加属性,例如

<TextBox Text="{Binding Path=Entity.TextValue}" OSK.PopupKeyboard.UIElementControl="{How do I bind this to this parent control?}"/>

What I'd like to do is pass the parent control such as the textbox to the keyboard, set the preview bar along the top of my keyboard to be the same type with the same bindings as the underlying control that a user clicked on to summon the keyboard. 我想做的是将诸如文本框之类的父控件传递给键盘,将键盘顶部的预览栏设置为与用户单击以召唤的基础控件具有相同绑定类型的类型。键盘。 This way the values that are entered into the preview on the keyboard are reflected on the control that the user clicked to summon the keyboard in the first place. 这样,输入到键盘预览中的值将首先反映在用户单击以召唤键盘的控件上。 I also figure it'll allow the keyboard to be flexible with the type of controls that can be used to summon it. 我还认为,这将使键盘具有可用于召唤的控件类型灵活。

So I've figured out what I needed to do in this instance. 所以我想出了在这种情况下需要做的事情。 I needed to create a dependency property of type FrameworkElement. 我需要创建一个类型为FrameworkElement的依赖项属性。 On my on screen keyboard UserControl I needed a ContentControl to hold the FrameworkElement type. 在屏幕键盘UserControl上,我需要一个ContentControl来容纳FrameworkElement类型。 Naturally you have to disconnect the FrameworkElement from its original parent as it can't be in the visual tree more than once, store the parent, attach it to the new parent (ContentControl) then when you're done, reattach it to its original parent. 自然,您必须断开FrameworkElement与原始父级的连接,因为它不能多次出现在可视树中,存储父级,将其附加到新父级(ContentControl),然后完成后,将其重新附加到其原始父级父母

    public static readonly DependencyProperty FrameworkElementProperty =
            DependencyProperty.RegisterAttached("FrameworkElement",
            typeof(FrameworkElement),
            typeof(PopupKeyboard),
            new FrameworkPropertyMetadata(default(FrameworkElement),
                new PropertyChangedCallback(PopupKeyboard.OnFrameworkElementChanged)));

        [AttachedPropertyBrowsableForType(typeof(FrameworkElement))]
        public static FrameworkElement GetFrameworkElement(DependencyObject element)
        {
            if (element == null)
                throw new ArgumentNullException("element");

            return (FrameworkElement)element.GetValue(FrameworkElementProperty);
        }

        public static void SetFrameworkElement(DependencyObject element, bool value)
        {
            if (element == null)
                throw new ArgumentNullException("element");

            element.SetValue(FrameworkElementProperty, value);
        }

private static void OnFrameworkElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement fe = d as FrameworkElement;
            if (fe != null)
            {
                // detach here
                keyboard.FrameworkElement = fe;
            }
        }

If I wanted to bind a control such as TextBox, ComboBox etc, I'd use the markup as follows: 如果我想绑定诸如TextBox,ComboBox等的控件,则可以使用如下标记:

<TextBox Content="{Binding Entity.Value}" local:PopupKeyboard.FrameworkElement="{Binding RelativeSource={RelativeSource Self}}" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM