I'm trying to learn AvaloniaUI. I would like to know how DirectProperties work.
So: I created a UserControl: TestUC I added a DirectProperty in it: Value I added 4 TextBoxes. 2 of them in the MainView and 2 in the TestUC. I added bindings to the "greeting" field in the MainViewModel.
I try to sync all 4 TextBoxes. Just to learn how DirectoProperty works. The 2 TextBoxes in the TestUC are not synced with the others. So It looks like I miss something with DirectProperties.
I have a github repo here to show this.
What do I miss?
Here is the relevant part in MainView.axaml
<StackPanel>
<Label Content="First in MainView"/>
<TextBox Text="{Binding Greeting}" HorizontalAlignment="Stretch"/>
<Label Content="Second in MainView"/>
<TextBox Text="{Binding Greeting}" HorizontalAlignment="Stretch"/>
<Label Content="UserControl"/>
<uc:TestUC Value="{Binding Greeting}"/>
</StackPanel>
TestUC.axaml
<StackPanel>
<TextBox Text="{Binding Value,Mode=TwoWay}"/>
<TextBox Text="{Binding Value,Mode=TwoWay}"/>
</StackPanel>
TestUC.axaml.cs
public static readonly DirectProperty<TestUC, string> ValueProperty =
AvaloniaProperty.RegisterDirect<TestUC, string>(
nameof(Value),
o => o.Value,
(o, v) => o.Value = v,
defaultBindingMode: BindingMode.TwoWay);
private string _value;
public string Value
{
get { return _value; }
set { SetAndRaise(ValueProperty, ref _value, value); }
}
User Controls is not design for this scenarios ...look at Types of Custom Controls Templated control is what I will choose
StyledProperty
is more suited than DirectProperty
, because your property will use the Avalonia Style system
the following is what you want create a Templated control called MyContorl
in Controls namespace
public class MyControl : TemplatedControl
{
public static readonly StyledProperty<string> ValueProperty =
AvaloniaProperty.Register<MyControl, string>(
nameof(Value),
defaultBindingMode: BindingMode.TwoWay);
public string Value
{
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
}
and create a template for it
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:TestAvalonia.Controls">
<Design.PreviewWith>
<controls:MyControl />
</Design.PreviewWith>
<Style Selector="controls|MyControl">
<!-- Set Defaults -->
<Setter Property="Template">
<ControlTemplate>
<StackPanel>
<Label Content="one way binding"/>
<TextBox Text="{TemplateBinding Value}"/>
<Label Content="Two way binndign"/>
<TextBox Text="{Binding Value,Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
</StackPanel>
</ControlTemplate>
</Setter>
</Style>
</Styles>
and include this style in your Application style
<StyleInclude Source="/Controls/MyControl.axaml"/>
finally use it as you expect
xmlns:controls ="using:TestAvalonia.Controls"
....
<Label Content="controls"/>
<controls:MyControl Value="{Binding Greeting}"/>
I have create Pull request in your GitHub with this changes