1
votes

i created my first WPF MVVM pattern solution. I created a UserControl and I would like to reuse this control in my MainWindow, because style is the same only differents between this both controls are the datasource. First Control uses ObervableCollection index 0 and second UserControl uses from the same OberservableCollection index 1. The observablecollection is in my Mainviewmodel and the binding works well, if I make the binding inside of my UserControl.

Dont want to bind inside of the UserControl to my model like this:

UserControl:

   <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="PersonModel.FirstName"></TextBlock>
        <TextBlock Grid.Row="1" Text="PersonModel.FirstName"></TextBlock>
    </Grid>

I would like to bind each nested control of my Usercontrol in my MainWindow.

MainWindow.xaml

<desktop:UserControl1 Textblock1.Text="{Binding PersonModel.FirstName} TextBlock2.Text="{Binding PersonModel.LastName}"></desktop:UserControl1>
1
Similar question and some answers stackoverflow.com/questions/19491951/…Shazter

1 Answers

1
votes

It's easy to expose anything bindable as UserControl dependency properties, here is CustomText one:

public partial class UserControl1 : UserControl
{
    public string CustomText
    {
        get { return (string)GetValue(CustomTextProperty); }
        set { SetValue(CustomTextProperty, value); }
    }
    public static readonly DependencyProperty CustomTextProperty =
        DependencyProperty.Register("CustomText", typeof(string), typeof(UserControl1), new PropertyMetadata());

    public UserControl1()
    {
        InitializeComponent();
        DataContext = this;
    }
}

In xaml you bind to it:

<UserControl ... >
    <TextBlock Text="{Binding CustomText}"  />
</UserControl>

And the usage will be:

<local:UserControl1 CustomText="{Binding SomeProperty" />

Another approach is to use callback of dependency property, this way you can change many things in code behind of UserControl, e.g. start animation.

I don't know if there is a way to expose complete child control of UserControl, but maybe you don't need that (rather create few dedicated dependency properties to change specific property of specific control).


One more possibility is to give UserControl a name and use it in code behind of window. In such case you can expose UserControl controls by giving them names (x:Name) and using properties:

public partial class UserControl1 : UserControl
{
    public TextBlock TextBlock => textBlock; // textBlock is x:Name
    ...
}

Now you can bind in code to e.g. userControl1.TextBlock.Visibility (where userControl1 is an x:Name of <local:UserControl1 />).