Click here to Skip to main content
12,818,816 members (32,545 online)
Rate this:
Please Sign up or sign in to vote.
See more: C# WPF
Defined two user controls UC1 and UC2, both UC1 and UC2 have a public variable commonVar, button1

I have a button click function on a subform inside UC1/UC2

It works if I implicit converted Parent to UC1

UC1 mainForm = grid_Form.Parent;
mainForm.commonVar = "111";

Infact, I would like to do something like
UserControl mainForm = grid_Form.Parent;
// Share coding
mainForm.button1.Content = "Same Value";
// Different coding using if clause
if (grid_Form.Parent.GetType().Contains("UC1"))
   mainForm.commonVar = "111";  // This is variable on UC1
} else {
   mainForm.commonVar = "222";  // This is variable on UC2

However, it compiles failed as UserControl do not have commonVar and button1.
I do not want to duplicate coding in if clause, any idea? thanks.
Posted 20-Feb-13 17:49pm
Updated 20-Feb-13 17:52pm

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

You don't understand WPF the class hierarchy of framework elements. If WPF, a control is contained in an instance of a class, which itself is not a control. Take for example Panel. It contains control, but look at its class hierarchy:[^].

So, the question is not posed correctly and cannot be answered like this. Note that you did not explain your ultimate goal. Always do it, then, even if your question is based on some misconception, you will have a chance to get a useful constructive advice anyway.

In this case, this is a bit harder, but I can suggest you to learn certain things in related fields.

First of all, you need to understand WPF content model:[^].

More advanced stuff is the hierarchy of UI framework elements. Perhaps it's more complex that you thought: there are two related trees: the Logical Tree and the Visual Tree. They are related but conceptually very different. You can access both of them, for different purposes. Please see:[^].

See also:[^].

This CodeProject article can also be useful: Understanding the Visual Tree and Logical Tree in WPF[^].

In most cases, you never care about those hierarchies, but in some advanced strategies, if, for example, you need to find something in generic UI-agnostic ways, you need to use one tree or another.


Firstly, you are trying to use wrong conception "find which button was clicked". Instead, you need to write individual event handler to each button. This is the primary use of such events.

Secondly, you are trying to make things way more complex they have to be.

If your layout is already in XAML, add one thing: add Name to each of your labels in question. It will give you access the them in code. And you probably already have names for buttons. As your names violate naming conventions, lets assume the names are:
Button buttonFirst = //..
Button buttonSecond = //..
Label labelFirst = //..
Label lableSecond = //..

The lines above are not in source code, but they will appear in the intermediate auto-generated C# code, generated from your XAML and will be compiled with your project in a usual way. (By the way, good to understand: this is how XAML of the window works.)

Add your events handles to the invocation lists of your events:

buttonFirst.Click += (sender, eventArgs) => {
    labelFirst.Content = CalculateText(sender);
buttonSecond.Click += (sender, eventArgs) => {
    labelSecond.Content = CalculateText(sender);

It does not look like code reuse, but it shows you the use of anonymous methods: your method CalculateText may have different signature then the handler (anonymous) itself; the code of handler can be anything or the same, you can use sender and eventArgs or not.

Normally, the even handlers do different things, and no reuse needed. The reuse is needed in more rare situations when the handlers do very similar things, as in your example. But in this case, you can use a loop with arrays (or any other collections) of controls.

And of course you can use the Logical Tree, Visual Tree or both, but analyze the need for it.

If your task itself is so much ad-hock as it seems, don't seek universal solution, but seek them when the problem itself is very universal. For example, do it if you need some methods applicable for any thinkable forms.

swissivan 21-Feb-13 3:01am
I am new to WPF and sorry about any inconvenience caused.

I explain my goal here.
-Reduce the duplication of coding when modify the parent's label.

Details as below:

My Solution Hierarchy

MainWindow using
UC1 and UC2

using S

UC2 using S

which UserControl S has a button

When I click on UC1's S's button, I do want to modify a label on UC1
When I click on UC2's S's button, I do want to modify a label on UC2

The two labels are with the same name.

In code behind of S, I want to reduce duplicated code so I can just write one sentence to handle UC1 and UC2.

Just something like
s.Parent.label_title.Text = "SameValue"; // Error as s.Parent do not have label_title and compile failed

I have to cast s.Parent to UC1 or UC2
(s.Parent as UC1).label_title.Text = "SameValue"; // Compile success but how about UC2?

I have to duplicate the code to
if (UC1)
(s.Parent as UC1).label_title.Text = "SameValue";
} else {
(s.Parent as UC2).label_title.Text = "SameValue";

I want to prevent the duplicated code, is there any method or syntax that can help?

In the mean time, I will have more study on WPF and Content Model Structure, thanks.
Sergey Alexandrovich Kryukov 21-Feb-13 11:19am
I answered, see updates solution, after [EDIT].
swissivan 22-Feb-13 2:50am
Thanks again!
Sergey Alexandrovich Kryukov 22-Feb-13 11:27am
You are very welcome.
Good luck in mastering of all this stuff, call again.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web02 | 2.8.170308.1 | Last Updated 21 Feb 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100