creating a reusable user control in WPF

11,156

Yeah that should be very easy, either create a lookless control with DataTemplate, or just create a standard UserControl. Trick it to set its DataContext to a full Address object

<local:AddressControl DataContext="{Binding BillingAddress}"/>

Which would allow your new "AddressControl" to have markup something like this

<StackPanel Orientation="Vertical">
<Label Content="City"/>
<TextBox Content="{Binding City}"/>

<Label Content="ZipCode"/>
<TextBox Content="{Binding ZipCode}"/>

<Label Content="ZipCode"/>
<TextBox Content="{Binding ZipCode}"/>

<Label Content="Number"/>
<TextBox Content="{Binding Number}"/>
</StackPanel>
Share:
11,156
Max
Author by

Max

Updated on June 14, 2022

Comments

  • Max
    Max almost 2 years

    In the (fairly large) LOB application we are building with WPF for UI we have a lot of viewmodels that contain the same kind of data sub-object. For example, there are a lot of addresses

    public class AddressViewModel : INotifyPropertyChanged
    {
    
       public string City {...}
       public string ZipCode {...}
       public string Address {...}
       public string Number {...}
    
      // INPC logic omitted 
    }
    

    scattered among business objects:

    public class CustomerViewModel : INotifyPropertyChanged
    {
         public string Name {...}
         public AddressViewModel BillingAddress {...}
         public AddressViewModel DeliveryAddress {...}
         /*
         ...
         */
    }
    

    is it possible to build a reusable custom User Control which we can bind to any address sub-object?

    In a view (possibly another custom user control) designed to edit customer details we would like to put a custom control like this

    <UserControl x:Class="OurApp.View.AddressEditor"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
    
            <TextBox x:Name="ZipCode" Text="{Binding Path=ZipCode, UpdateSourceTrigger = PropertyChanged}" Validation.ErrorTemplate="{x:Null}" HorizontalAlignment="Left" Height="23" Margin="10,19,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Width="120" />
    
             <!-- other fields for the rest of AddressViewModel properties-->
    
        </Grid>
    
    </UserControl>
    

    that we can simply use like this in a view bound to a CustomerViewModel instance

     <TextBox x:Name="Name" Text="{Binding Path=Name, UpdateSourceTrigger = PropertyChanged}" Validation.ErrorTemplate="{x:Null}" />
    
    <AddressEditor SomeProperty="{something that points to BillingAddress}" />
    <AddressEditor SomeProperty="{something that points to DeliveryAddress}" />
    

    What is the correct way to do this? We tried to point the binding to BillingAddress but we did not find a working way...

    Thanks in advance for any contribution,

  • Max
    Max over 11 years
    Actually this is the same method I tried first before asking here but it did not work because in my experimental code BillingAddress and DeliveryAddress where members and not properties (my fault), I was a bit surprised I could not get WPF to work in this simple case :)
  • Max
    Max over 11 years
    Actually this is the same method I tried first before asking here but it did not work because in my experimental code BillingAddress and DeliveryAddress where members and not properties (my fault), I was a bit surprised I could not get WPF to work in this simple case :) Now it is working!
  • Pakk
    Pakk about 8 years
    This is the best solution so far of all 50 pages I've searched on how to - thanks