如何在ControlTemplate中向对象添加事件处理程序

时间:2011-07-22 21:28:40

标签: silverlight silverlight-4.0 controltemplate

如何以编程方式将事件处理程序添加到仅存在于另一个对象的ControlTemplate中的对象?

我使用Silverlight 4.我想使用来自第三方DLL(Liquid)的控件ColorSelector。它看起来像组合框,但实现方式不同。 (当没有系统ComboBox时,它可能是为旧版Silverlight而制作的。)ColorSelector类派生自ContentControl,它的外观是使用xaml文件中定义的ControlTemplate实现的。

事实上,它是一个看起来像组合框的控件,但是以编程方式,它的对象不是从组合框派生的。现在我卡住了,因为我想以编程方式访问我在屏幕上看到的组合框对象。通常,如果它是一个真正标准的ComboBox,我会使用事件DropDownOpened和DropDownClosed来分别知道何时显示和隐藏框。但是这个颜色选择器不提供这些事件。但它使用ControlTemplete,它将ColorSelector的外观定义为DropDown对象。 DropDown类是来自同一个dll的另一个类,它的外观也是由它的ControlTemplate定义的,那就是那个类似神秘的组合框外观的地方。我现在对此完全感到困惑。

我如何以编程方式访问这些我可以在屏幕上看到但不直接出现在代码中的视觉控件?这是一个简单的例子:

class ColorSelector : LiquidControl
class LiquidControl : ContentControl

<Style TargetType="local:ColorSelector">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:ColorSelector">
                <local:DropDown x:Name="RootElement">
                .....
                </local:DropDown>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

class DropDown : LiquidControl

<Style TargetType="local:DropDown">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:DropDown">
                <Grid x:Name="RootElement">
                    <Button x:Name="ElementButton">
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

现在我在我的代码(new ColorControl())中创建一个新的ColorControl,然后我想访问DropDown模板中定义的那个按钮。怎么做?

2 个答案:

答案 0 :(得分:1)

我相信你没有控件的源代码。试试这个:延长ColorSelector覆盖OnApplyTemplate来电GetTemplateChild来获取按钮。

public override void OnApplyTemplate()
{
   var button = this.GetTemplateChild("ElementButton") as Button;
   .... Do whatever with button
   base.OnApplyTemplate();
}

答案 1 :(得分:0)

我找到了原始DLL更改问题的解决方案。它基于anivas给出的答案。我把这段代码放到DropDown.OnApplyTemplate

        ElementPopup.Opened += (s, ea) => { DropDownOpened(this, ea); };
        ElementPopup.Closed += (s, ea) => { DropDownClosed(this, ea); };

这两个事件分别在组合框打开和关闭时发出信号。 (Combobox是使用我以前不理解的模板实现的,有Popup对象可以显示打开的组合框。)

然后,类似地,我向ColorSelector.OnApplyTemplate添加了类似的代码:

        _dropDown.DropDownOpened += (s, ea) => { DropDownOpened(this, ea); };
        _dropDown.DropDownClosed += (s, ea) => { DropDownClosed(this, ea); };

现在我在ColorSelector中有两个新事件,它们在打开或关闭时发出信号。这就是我想要的。

感谢anivas!他的回答本身并没有起作用,但它告诉我从哪里开始。 (如果我派生了ColorSelector类,我丢失了它的模板和路由事件。而且它也使用DropDown,必须以某种方式改变它。)