locked
how to reference a named object from within a usercontrol? RRS feed

  • Question

  • Hi, all. Imagine the following:

    • I have a MainWindow that contains a panel (named "myCanvas") and a usercontrol (named "myUC").
    • myUC is outside of myCanvas.
    • The goal is to click on myUC to set properties of myCanvas.

    Unfortunately, I cannot figure out how to reference myCanvas from within myUC. In Flash/ActionScript, I would just use something like "parent.myCanvas" (or whatever), but I can't find any equivalent notation in C#/WPF.

    Help? Thanks in advance.

    Monday, August 20, 2012 12:12 PM

All replies

  • Are you talking about from the codebehind file for myUC? (myUC.xaml.cs for example) 

    If so, that is difficult, because of the way UserControls and classes in general work in xaml. They are meant to encapsulate functionality, and as such they don't have an easy way to know about things outside of their own class/file.

    That said, you can find things from the visual tree by name, so you could do something like this:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication3
    {
    	/// <summary>
    	/// Interaction logic for myUC.xaml
    	/// </summary>
    	public partial class myUC : UserControl
    	{
    		public myUC()
    		{
    			this.InitializeComponent();
    		}
    
    		private void Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			// TODO: Add event handler implementation here.
    			var parent = VisualTreeHelper.GetParent(this) as FrameworkElement;
    
    			Canvas target = null;
    			while (parent != null)
    			{
    				var possibleCanvas = parent.FindName("myCanvas") as Canvas;
    				if (possibleCanvas != null)
    				{
    					target = possibleCanvas;
    					break;
    				}
    
    				parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
    			}
    
    			if (target != null)
    			{
    				target.Background = new SolidColorBrush(Colors.Green);
    			}
    		}
    	}
    }

    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:local="clr-namespace:WpfApplication3"
    	x:Class="WpfApplication3.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480">
    
    	<Grid x:Name="LayoutRoot">
    		<Canvas x:Name="myCanvas" HorizontalAlignment="Left" Height="86" Margin="90,86,0,0" VerticalAlignment="Top" Width="139" Background="Red"/>
    		<local:myUC x:Name="myUC" Margin="258,219,266,122"/>
    	</Grid>
    </Window>

    Monday, August 20, 2012 3:56 PM
    Moderator
  • Thank you, Chuck, I will try that.

    I'm new to XAML, so it helps to know how things are intended to work. Is the idea, then, that UserControls are not really meant for influencing other elements? That's not the same for standard controls, though, right?

    • Edited by ragamoffyn Monday, August 20, 2012 7:19 PM
    Monday, August 20, 2012 7:17 PM
  • Generally you can influence things within the same xaml file. There are a lot of exceptions, but for simple things that is true. UserControls are meant to be "self contained" things that can be reused elsewhere as well.  However, a UserControl could expose properties and events that you can interact with more easily as an instance of that UserControl as well.
    Monday, August 20, 2012 8:16 PM
    Moderator