在以下结构中
<Border ...>
<ItemsControl>
<ItemsControl.Template>
<DataTemplate>
<ACustomElement>
<Border MouseLeftButtonDown="method1">
</ACustomElement>
</DataTemplate>
</ItemsControl.Template>
</ItemsControl>
</Border>
我想从method1()内部调用ACustomElement类中的公共方法。
到目前为止我在method1()中尝试了什么:
var cr = ((Border)sender).Parent;
cr.method2();
method2是我的ACustomElement类中的公共方法。但它似乎没有认识到这种方法。
我收到以下错误:
'DependencyObject'不包含'method2'的定义,并且没有可以找到接受类型'DependencyObject'的第一个参数的扩展方法'method2'(你是否缺少using指令或汇编引用?)
有关如何解决此问题的任何建议? 当然,我只是错过演员或其他什么......
编辑:以下样式将始终应用于ACustomElement:
<Style TargetType="{x:Type c:ACustomElement}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type c:ACustomElement}">
<ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
答案 0 :(得分:2)
您必须将cr
转换为ACustomElement类型
var cr = (ACustomElement)((Border)sender).Parent;
cr.method2();
否则,您的cr
变量引用了异常中所见的DependencyObject类型。
如果您不确定层次结构,请使用此方法查找特定类型的父级。
private T FindParent<T>(DependencyObject child) where T : DependencyObject {
var parent = VisualTreeHelper.GetParent(child) as T;
if (parent != null)
return parent;
return FindParent<T>(parent);
}
// usage
private void method1(object sender, MouseButtonEventArgs e)
{
var cr = FindParent<ACustomElement>((Border)sender);
}
此外,DateTemplate可以是ItemsControl.ItemTemplate的子项,但不是ItemsControl.Template的子项(需要ControlTemplate)
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ACustomElement>
<Border MouseLeftButtonDown="method1" />
</local:ACustomElement>
</DataTemplate>
</ItemsControl.ItemTemplate>
<强>更新强>
正如我在问题的评论中指出的那样,直接向您的类型添加事件处理程序或绑定命令。你为什么这么复杂?
答案 1 :(得分:0)
尝试将Tag
的{{1}}属性绑定到自定义控件:
Border
...并在事件处理程序中强制转换<ACustomElement>
<Border MouseLeftButtonDown="method1" Tag="{Binding RelativeSource={RelativeSource AncestorType=ACustomElement}}">
</ACustomElement>
属性:
Tag
答案 2 :(得分:-1)
ngRepeat
是安全和正确的。
正如您所怀疑的那样,您错过了演员阵容,但模式匹配方法比直接添加演员阵容更具可读性和弹性。
编译错误的原因是if (sender is Border b && b.Parent is ACustomElement c)
{
c.method2();
}
只是键入为表示父元素的常规类型,而不是您创建的自定义元素类的实例。