tags:

views:

40

answers:

3

Hi all. I have a UserControl that looks like this:

<UserControl x:Class="Test3.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Grid>
        <Button Name="mybutton" Content="Button Content"/>
    </Grid>
</UserControl>

And a main window that uses it like so:

<Window Name="window_main" x:Class="Test3.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Test3">

    <StackPanel>
        <Label Name="mylabel" Content="Old Content"/>
        <local:UserControl1/>
    </StackPanel>
</Window>

What I want to happen, is for mybutton's click event handler to set the content of mylabel to "New Content". However, it appears that this is impossible. Is there in fact a way to do this?

A: 

There are several solutions:

The quick and dirty: on mybutton's click event handler, find the parent Window using VisualTreeHelper, then do a ((Label) window.FindName("mylabel")).Content = "New Content".

The clean WPF way: create a new class, add a property object LabelContent and a property ICommand ChangeContentCommand, that will change LabelContent on execution. Set this class as the DataContext of the window, bind the Content of mylabel to LabelContent and the Command property of mybutton to ChangeContentCommand (the user control will inherit the data context).

Julien Lebosquain
A: 

The simplest way to do what you describe is to take advantage of event routing and just add a handler in the Window XAML:

<StackPanel ButtonBase.Click="Button_Click">
    <Label Name="mylabel" Content="Old Content"/>
    <local:UserControl1/>
</StackPanel>

and the handler method:

private void Button_Click(object sender, RoutedEventArgs e)
{
    mylabel.Content = "New Content";
}

I suspect you probably have some more complications to this in your real application so you may need to do more to verify that the click is coming from the correct button by checking some properties on it.

John Bowen
+1  A: 

I have chosen to answer this myself since my solution ended up being a bit more complete. I don't fully understand the "right" way to do this, but this is how I did it:

Window1 window_reference = (Window1)(Window1.GetWindow((Button)sender));

After this, the children (such as other xaml controls) of the main window can be seen at compile-time.

Additionally, a more direct way of doing this is to have a public member of the UserControl like so:

namespace UIDD_Test
{
    public partial class UserControl1 : UserControl
    {
        public Window1 window_reference;

        public UserControl1()
        {
            InitializeComponent();
        }
    }
}

Then whenever appropriate, you can set that member to reference whatever window you want. In my case I have a Window1 class which is derived from Window, so I can set that member of the UserControl1 class like so:

myusercontrol.window_reference = window_main;

Where I've set up the xaml like so:

<local:UserControl1 x:Name="myusercontrol"/>

And window_main is the Name of the main window (it's a Window1 class).

Adam S