如何为模板元素做一个事件?

时间:2011-10-24 07:50:57

标签: c# .net wpf xaml user-controls

我有没有机会在WPF中创建一个事件来控制模板而不创建UserControl等等? 例如:创建的窗口模板具有自定义“关闭(X)”按钮。它对每个窗口都有相同的操作。它有机会使它运作吗?给Click事件关闭窗口?

我的意思是像这样使用它:

<Window style="{StaticResource MyWindowTemplate}">...</Window>

并没有创建自定义Window类,因为我希望有机会将它用于每个Windows类。

所以有机会这样做吗?或者任何类似或更好的解决方案?

1 个答案:

答案 0 :(得分:2)

我不认为Template可以实现一种行为。它们是为了外观和感觉而不是行为。对于行为,我们附加了属性和行为,当附加到它们的有效目标依赖项对象时,它们的行为完全相同。

e.g。在你的情况下,右上角的关闭按钮是一个困难的按钮,但窗口上的任何按钮关闭目标UI,即当指定一些附加行为时窗口本身。

 <Window x:Class="..."
         ...>
    <Grid>
        <Grid.RowDefinitions>
           <RowDefinition Height="*"/>
           <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ContentControl ... />
        <Buton Width="100"
               Content="Close"
               local:CloseBehavior.IsCloseButton="True" />
   </Grid>
 </Window>

因此,在上面的示例中,任何配置了附加行为local:CloseBehavior.IsCloseButton="True"的按钮都会使该按钮单击以关闭其祖先窗口。

修改

CloseBehavior.IsCloseButton如下所示。因此,在下面的代码中,当我们将IsCloseButton附加属性设置为true对任何窗口上的任何按钮时,使用可视和逻辑遍历,附加行为将搜索祖先窗口,然后在单击时关闭它。

public static class CloseBehavior
{
    public static readonly DependencyProperty IsCloseButtonProperty
        = DependencyProperty.RegisterAttached(
            "IsCloseButton",
            typeof (bool),
            typeof (CloseBehavior),
            new PropertyMetadata(
               false,
               OnIsCloseButtonPropertyChanged));

    private static void OnIsCloseButtonPropertyChanged
        (DependencyObject depObj,
         DependencyPropertyChangedEventArgs e)
    {
        var buttonBase = depObj as ButtonBase;
        if (buttonBase != null && (bool)e.NewValue)
        {
            buttonBase.Click
                += (o, args) =>
                    {
                        var window
                            = GetVisualLogicalParent(
                                  buttonBase,
                                  typeof(Window)) as Window;

                        if (window != null)
                        {
                            window.Close();
                        }
                    };
        }
    }

    public static bool GetIsCloseButton(DependencyObject depObj)
    {
        return (bool)depObj.GetValue(IsCloseButtonProperty);
    }

    public static void SetIsCloseButton(
        DependencyObject depObj,
        bool value)
    {
        depObj.SetValue(IsCloseButtonProperty, value);
    }

    public static DependencyObject GetVisualLogicalParent(
       DependencyObject depObj,
       Type type)
    {
        if (depObj != null)
        {
            var parent = VisualTreeHelper.GetParent(depObj);
            if (parent == null)
            {
                parent = LogicalTreeHelper.GetParent(depObj);
            }
            if (parent != null)
            {
                if (type.IsInstanceOfType(parent))
                {
                    return parent;
                }
                else
                {
                    return GetVisualLogicalParent(parent, type);
                }
            }
        }

        return null;
    }
}

我希望这会有所帮助。