WPF获取父控制 [英] WPF Get Parent Control

查看:90
本文介绍了WPF获取父控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

定义了两个用户控件UC1和UC2,UC1和UC2都有一个公共变量commonVar,button1



我在UC1内的子窗体上有一个按钮点击功能/ UC2



如果我将父母隐含转换为UC1



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
}





然而,由于UserControl没有commonVar和button1,它编译失败。

我不想在if子句中重复编码,任何想法?谢谢。



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.

推荐答案

你不了解WPF框架元素的类层次结构。如果是WPF,则控件包含在类的实例中,该类本身不是控件。例如 Panel 。它包含控件,但请查看其类层次结构:

http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.aspx [ ^ ]。



所以,问题没有正确提出,不能像这样回答。请注意,您没有解释您的最终目标。总是那么做,那么,即使你的问题是基于一些误解,你仍然有机会获得有用的建设性建议。



在这种情况下,这个有点困难,但我可以建议你学习相关领域的某些事情。



首先,你需要了解WPF 内容模型 http://msdn.microsoft.com/en-us/library/bb613548.aspx [ ^ ]。



更高级的东西是UI框架元素的层次结构。也许你认为它更复杂:有两个相关的树:逻辑树 Visual Tree 。它们是相关的,但在概念上却非常不同。您可以出于不同目的访问它们。请参阅:

http://msdn.microsoft.com/en-us /library/ms753391.aspx [ ^ ]。



另请参阅: http://wpftutorial.net/ LogicalAndVisualTree.html [ ^ ]。



此CodeProject文章也很有用:了解WPF中的可视树和逻辑树 [ ^ ]。



在大多数情况下,你从不关心这些层次结构,但是在某些高级策略中,例如,你需要以通用的UI无关的方式找到一些东西,你需要使用一棵树或另一棵树。







首先,你试图使用错误的概念找到点击了哪个按钮。相反,您需要为每个按钮编写单独的事件处理程序。这是这类活动的主要用途。



其次,你正试图让事情变得更加复杂。



如果您的布局已经在XAML中,请添加一项内容:为每个相关标签添加名称。它将允许您在代码中访问它们。你可能已经有了按钮的名字。由于您的名字违反了命名约定,我们假设名称为:

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.



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 = //..





上面的行不在源代码中,但是它们将出现在从XAML生成的中间自动生成的C#代码中,并将以通常的方式与您的项目一起编译。 (顺便说一下,很好理解:这就是窗口的XAML如何工作。)



将事件句柄添加到事件的调用列表中:





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);
};





它看起来不像代码重用,但它向您展示了匿名方法的使用:您的方法 CalculateText 可能有不同的签名然后处理程序(匿名)本身;处理程序的代码可以是任何或相同,您可以使用 sender eventArgs



通常,偶数处理程序会执行不同的操作,并且不需要重用。当处理程序执行非常类似的操作时,在更罕见的情况下需要重用,如示例所示。但在这种情况下,您可以使用带有数组(或任何其他集合)控件的循环。



当然,您可以使用逻辑树,可视树或两者,但分析它的需要。



如果你的任务本身就像看起来那么多,那么就不要寻求通用解决方案,而是在问题本身非常普遍时寻求它们。例如,如果你需要一些适用于任何可以想象的形式的方法,那就去做吧。



-SA



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


这篇关于WPF获取父控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆