-2

在以下结构中

<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>
4

2 回答 2

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>

更新

正如我在对问题的评论中指出的那样,直接将事件处理程序添加到您的类型或绑定命令。你为什么把事情搞得这么复杂?

于 2017-12-12T09:53:34.137 回答
0

尝试将 的Tag属性绑定Border到自定义控件:

<ACustomElement>
    <Border MouseLeftButtonDown="method1" Tag="{Binding RelativeSource={RelativeSource AncestorType=ACustomElement}}">
</ACustomElement>

...并Tag在事件处理程序中转换属性:

var cr = sender as Border;
var ctrl = cr.Tag as ACustomElement;
ctrl.method2();
于 2017-12-12T10:13:18.260 回答