控制模板中的UWP双向绑定

时间:2019-06-11 21:05:08

标签: wpf uwp binding win-universal-app custom-controls

我有一个带有Text属性的自定义控件,该控件应双向绑定到数据上下文的属性。
绑定仅发生在开始时(我想是一次),但不响应任何文本更改。

我的自定义控件:

public sealed class MyTextControl : Control
{
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text", typeof(string), typeof(MyTextControl), new PropertyMetadata(default(string)));

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

    public MyTextControl()
    {
        DefaultStyleKey = typeof(MyTextControl);
    }
}

控制模板:

<Style TargetType="local:MyTextControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyTextControl">
                <Border
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">

                    <TextBox
                        BorderBrush="Black"
                        BorderThickness="1"
                        Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我正在调用控件:

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <myTextControl:MyTextControl
        Width="500"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Text="{x:Bind Greeting, Mode=TwoWay}" />

    <Button
        Margin="50"
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Content="Submit" />
</StackPanel>

问候是设置为Hello World后面代码中的DP!

我希望在“问候语”或“文本文字更改”中达到一个转折点,但我没有。
似乎双向绑定无法正常工作。 与WPF有什么不同吗?我该如何运作?

2 个答案:

答案 0 :(得分:0)

WPF的小变化需要一些时间来理解
我还需要更新模板以支持双向绑定

Text="{Binding Path=Text, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />

曾经有一段时间我们有了FrameworkPropertyMetaData,但没有更多...

答案 1 :(得分:0)

快速解答

首先,a {TemplateBinding} is always a one-way binding

第二,从Windows 10版本1809 you can use the {x:Bind} markup extension anywhere you use {TemplateBinding} in a ControlTemplate开始。

因此,您可以在{x:Bind}内使用ControlTemplate而不是{TemplateBinding},并且具有双向绑定功能mode=TwoWay)。 / p>

额外帮助

说过,在{x:Bind}中使用ControlTemplate并不像用{TemplateBinding}替换{x:Bind}的实例那样简单。它涉及其他一些更改。考虑到Visual Studio会自动(1)创建一个名为MyControl.cs的类文件,并且(2)在ControlTemplate中使用SomeProject\Themes\Generic.xaml分配控件的样式(如果文件夹和资源文件不在(它们已经存在,它们已经创建了),按照以下说明使您的控件与{x:Bind} 一起使用:

  1. 记住TargetType property is required (not optional) on ControlTemplate when using {x:Bind}

  2. 在文件夹Themes\中,创建一个名为Generic.xaml.cs的新类文件,并使用一个仅调用{{1}的公共构造函数声明一个名为Generic的公共密封局部类。 }:

    InitializeComponent

    (请参阅注释A。)

  3. 将以下内容作为属性添加到// Themes\Generic.xaml.cs namespace SomeSolution.SomeProject.Themes { public sealed partial class Generic { public Generic() => InitializeComponent(); } } 的根标记中:

    Generic.xaml

    (请参阅注释B。)

  4. 使用<!-- Themes\Generic.xaml --> <ResourceDictionary x:Class="SomeProject.Themes.Generic" ...> ... </ResourceDictionary> Generic)实例化包含控件样式的ready-xBind类型(Application.Resources):

    .MergedDictionaries

    (请参阅注释C,D和E。)


注释

A。 {x:Bind} markup extension generates source code at compile-time,因此需要初始化生成的代码]。

B。 x:Class joins partial classes在标记和代码隐藏之间]。

C。 A resource dictionary with code-behind is reused by instantiating its type(因此调用<!-- App.xaml --> <Application ...> <Application.Resource> <Generic xmlns="using:Whatever.Namespace" /> </Application.Resources> ... </Application> )而不是引用其文件名。

D。 Application.Resources can be reused everywhere。如果不希望这样做,则可以在InitializeComponentSomeFrameworkElement.Resources等中实例化具有样式的类。

E。 SomePage.Resources中的资源不需要与Themes\Generic.xaml进行“合并”,以便可以在任何地方使用。它们按惯例可用。但是,由于需要显式实例化该资源字典 ,因此无需命名文件Application.ResourcesGeneric.xaml(在Generic.xaml.cs之内)< / strong>。文件(和类)的名称可以不同,名称空间和位置也可以不同。 只要相应地实例化它们,该控件就会起作用