beatnikthedan
beatnikthedan

Reputation: 221

Re-use xaml bindings and behaviors that are common among several controls (UWP)

I have several TextBoxes that are using identical bindings and behaviors. Is there a way to set these in the textbox style or template or some other creative solution to have repeatable bindings and/or behaviors across multiple xaml controls?

Here is an example of what I'm doing, you can see the behaviors are the same, I have a lot of TextBoxes that will need the validate command behavior and the Text Binding will be the same for each control minus the Converter Parameter but I can bind that to either the control name or tag.

<TextBox x:Name="Control1"
                 Text="{x:Bind NewItem.Params,Mode=TwoWay,Converter={StaticResource DictionaryConverter},ConverterParameter=Control1,UpdateSourceTrigger=PropertyChanged}"
                 AllowFocusOnInteraction="True" 
                 Style="{StaticResource FormTextBox}" 
                 Grid.Row="1">
            <i:Interaction.Behaviors>
                <ic:EventTriggerBehavior EventName="LostFocus">
                    <ic:InvokeCommandAction Command="{x:Bind NewItem.CommandValidate}"/>
                </ic:EventTriggerBehavior>
            </i:Interaction.Behaviors>
        </TextBox>

<TextBox x:Name="Control2"
                 Text="{x:Bind NewItem.Params,Mode=TwoWay,Converter={StaticResource DictionaryConverter},ConverterParameter=Control2,UpdateSourceTrigger=PropertyChanged}"
                 Style="{StaticResource FormTextBoxNumber}"
                 Grid.Row="4">
            <i:Interaction.Behaviors>
                <ic:EventTriggerBehavior EventName="LostFocus">
                    <ic:InvokeCommandAction Command="{x:Bind NewItem.CommandValidate}"/>
                </ic:EventTriggerBehavior>
            </i:Interaction.Behaviors>
        </TextBox>

For those of you who always get extremely confused by my questions and bark up the wrong trees I'll try to re-iterate the best I can: What is a simple/creative way to re-use xaml bindings and behaviors that are common among several controls?

Upvotes: 0

Views: 156

Answers (1)

Nico Zhu
Nico Zhu

Reputation: 32775

For your requirement, you could use UserControl to encapsulate TextBox that block more details. For ease of testing I simplified your code. And this is my UserControl that only contain a TextBox.

<UserControl
    x:Class="BindTest.MyUseerControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BindTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <TextBox x:Name="MyTextBox" Text="{x:Bind Source.Params,Mode=TwoWay}"  AllowFocusOnInteraction="True"  Height="44">
        <i:Interaction.Behaviors>
            <ic:EventTriggerBehavior EventName="LostFocus">
                <ic:InvokeCommandAction Command="{x:Bind Source.CommandValidate}"/>
            </ic:EventTriggerBehavior>
        </i:Interaction.Behaviors>
    </TextBox>
</UserControl>

And Then I declared Source DependencyProperty that use to store data source.

public Info Source
{   
    get { return (Info)GetValue(SourceProperty); }
    set { SetValue(SourceProperty, value); }
}

public static readonly DependencyProperty SourceProperty =
    DependencyProperty.Register("Source", typeof(Info), typeof(MyUseerControl), new PropertyMetadata(0));

I also create Info model class.

public class Info
{
    public string Params { get; set; }
    public ICommand CommandValidate { get; set; }

    public Info()
    {
        this.Params = "Hi Nico";
        this.CommandValidate = new RelayCommand(()=> {

            Debug.WriteLine("This Method Invoke");

        });
    }
}

Usage

public MainPage()
 {
     this.InitializeComponent();
     Item = new Info();
 }
public Info Item { get; set; }


<local:MyUseerControl Source="{x:Bind Item}"/>

Upvotes: 1

Related Questions