Click here to Skip to main content
15,896,063 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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

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


Infact, I would like to do something like
C#
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
Updated 20-Feb-13 16:52pm
v2

1 solution

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:
http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.aspx[^].

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: http://msdn.microsoft.com/en-us/library/bb613548.aspx[^].

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:
http://msdn.microsoft.com/en-us/library/ms753391.aspx[^].

See also: http://wpftutorial.net/LogicalAndVisualTree.html[^].

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.

[EDIT]

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:
C#
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:

C#
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.

—SA
 
Share this answer
 
v2
Comments
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

UC1
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].
—SA
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.
—SA

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900