Home > front end >  TwoWay Binding to a UserControl Property - WinUI 3
TwoWay Binding to a UserControl Property - WinUI 3

Time:10-07

I have the following UserControl that is meant to be a pre-formatted TextBox with a label:

XAML:

    <UserControl
        x:Class="Aerloc.Components.LabeledTextBox"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Aerloc.Components"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="75"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <TextBox Text="{x:Bind Caption, Mode=TwoWay}" Style="{StaticResource LabelTextBox}" Grid.Column="0"/>
            <TextBox Text="{x:Bind Value, Mode=TwoWay}" IsEnabled="{x:Bind IsEditable, Mode=OneWay}" Style="{StaticResource FieldTextBox}" Grid.Column=1/>
        </Grid>
    </UserControl>

Code Behind:

    public sealed partial class LabeledTextBox : UserControl
    {
        public DependencyProperty CaptionProperty = DependencyProperty.Register(nameof(Value), typeof(string), typeof(LabeledTextBox), new PropertyMetadata(null));
        public DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Caption), typeof(string), typeof(LabeledTextBox), new PropertyMetadata(null));
        public DependencyProperty IsEditableProperty = DependencyProperty.Register(nameof(IsEditable), typeof(bool), typeof(LabeledTextBox), new PropertyMetadata(null));

        public string Caption
        {
            get => (string)GetValue(CaptionProperty);
            set => SetValue(CaptionProperty, value);
        }
        public string Value
        {
            get => (string)GetValue(ValueProperty);
            set => SetValue(ValueProperty, value);
        }
        public bool IsEditable
        {
            get => (bool)GetValue(IsEditableProperty);
            set => SetValue(IsEditableProperty, value);
        }

        public LabeledTextBox()
        {
            this.InitializeComponent();
        }
    }

I am having trouble with TwoWay Binding the Value passed into the UserControl. When I create the binding (code below) I get an error message saying "TwoWay binding target 'Value' must be a dependency property". How can I two way bind the Value in my UserControl to the ViewModel?

    <components:LabeledTextBox 
                Caption="First Name:"
                Value="{x:Bind ViewModel.SelectedUser.FirstName, Mode=TwoWay}" 
                IsEditable="{x:Bind ViewModel.IsAddEditModeEnabled}"/>

CodePudding user response:

DependencyProperty needs to be static readonly. You also have your DependencyProperties' name wrong.

Fix this,

public DependencyProperty CaptionProperty = 
    DependencyProperty.Register(
        nameof(Value),
        typeof(string),
        typeof(LabeledTextBox),
        new PropertyMetadata(null));

public DependencyProperty ValueProperty = 
    DependencyProperty.Register(
        nameof(Caption),
        typeof(string),
        typeof(LabeledTextBox),
        new PropertyMetadata(null));

to this,

public static readonly DependencyProperty CaptionProperty = 
    DependencyProperty.Register(
        nameof(Caption),
        typeof(string),
        typeof(LabeledTextBox),
        new PropertyMetadata(null));

public static readonly DependencyProperty ValueProperty = 
    DependencyProperty.Register(
        nameof(Value),
        typeof(string),
        typeof(LabeledTextBox),
        new PropertyMetadata(null));
  • Related