我有一个带有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有什么不同吗?我该如何运作?
答案 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} 一起使用:
记住TargetType
property is required (not optional) on ControlTemplate
when using {x:Bind}
。
在文件夹Themes\
中,创建一个名为Generic.xaml.cs
的新类文件,并使用一个仅调用{{1}的公共构造函数声明一个名为Generic
的公共密封局部类。 }:
InitializeComponent
(请参阅注释A。)
将以下内容作为属性添加到// Themes\Generic.xaml.cs
namespace SomeSolution.SomeProject.Themes
{
public sealed partial class Generic
{
public Generic() => InitializeComponent();
}
}
的根标记中:
Generic.xaml
(请参阅注释B。)
使用<!-- 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。如果不希望这样做,则可以在InitializeComponent
,SomeFrameworkElement.Resources
等中实例化具有样式的类。
E。 SomePage.Resources
中的资源不需要与Themes\Generic.xaml
进行“合并”,以便可以在任何地方使用。它们按惯例可用。但是,由于需要显式实例化该资源字典 ,因此无需命名文件Application.Resources
和Generic.xaml
(在Generic.xaml.cs
之内)< / strong>。文件(和类)的名称可以不同,名称空间和位置也可以不同。 只要相应地实例化它们,该控件就会起作用。