c# - 行为在 Style Setter 中无法正常工作

标签 c# windows-runtime winrt-xaml

在我的 Windows 运行时应用程序中,我有一个主题,其样式具有为 DoubleTapped 操作定义的 Behavior:

这些是 XML 命名空间:

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"

这是风格:

<Style x:Name="DisplayImage" TargetType="ScrollViewer">
    <Setter Property="VerticalScrollBarVisibility" Value="Hidden" />
    <Setter Property="HorizontalAlignment" Value="Left" />
    <Setter Property="ZoomMode" Value="Disabled" />
    <Setter Property="i:Interaction.Behaviors">
        <Setter.Value>
            <i:BehaviorCollection>
                <core:EventTriggerBehavior EventName="DoubleTapped">
                    <local:ScrollViewerDoubleTap />
                </core:EventTriggerBehavior>
            </i:BehaviorCollection>
        </Setter.Value>
    </Setter>
</Style>

这是我的行为:

[DefaultEvent(typeof(ScrollViewer),"DoubleTapped")]
public class ScrollViewerDoubleTap : DependencyObject, IAction
{
    public object Execute(object sender, object parameter)
    {
        ScrollViewer sv = (ScrollViewer)sender;
        if (sv.HorizontalScrollBarVisibility == ScrollBarVisibility.Disabled)
        {
            sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
        }
        else
        {
            sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
        }
        return sender;
    }
}

这就是我使用它的方式:

<ScrollViewer Style="{StaticResource Image}" MaxWidth="1067">
    <Border BorderBrush="Black" BorderThickness="1">
        <Image Source="MyImage.png"/>
    </Border>
</ScrollViewer>

当我双击具有这种风格的页面上的第一张图片时,效果非常好;但是,当我双击页面上的其他图像时,行为代码永远不会运行。我知道它永远不会运行,因为我用断点运行它,当我双击第一张图像而不是第二张图像时它会中断。我将不胜感激关于为什么会发生这种情况的任何提示。

最佳答案

这行不通,因为行为、操作或触发器被设计为附加到单个 元素。当您在样式的 setter 中定义它时,就像您试图将它与多个元素相关联一样,正如您已经看到的那样,仅当您与具有此样式的第一个元素交互时才会调用触发器。

有一种简单的方法可以解决这个问题。基本上,您需要确保与此样式关联的每个元素都有您创建的触发器的新实例。您可以将所有这些逻辑包装在一个附加属性中,然后您的样式将只需要引用该属性。

<Style x:Name="DisplayImage" TargetType="ScrollViewer">
    <Setter Property="VerticalScrollBarVisibility" Value="Hidden" />
    <Setter Property="HorizontalAlignment" Value="Left" />
    <Setter Property="ZoomMode" Value="Disabled" />
    <Setter Property="local:FrameworkElementEx.AttachBehaviors" Value="True" />
</Style>

这就是这个附加属性的实现方式。

public static class FrameworkElementEx
{
    public static bool GetAttachBehaviors(DependencyObject obj)
    {
        return (bool)obj.GetValue(AttachBehaviorsProperty);
    }

    public static void SetAttachBehaviors(DependencyObject obj, bool value)
    {
        obj.SetValue(AttachBehaviorsProperty, value);
    }

    public static readonly DependencyProperty AttachBehaviorsProperty =
        DependencyProperty.RegisterAttached("AttachBehaviors", typeof(bool), typeof(FrameworkElementEx), new PropertyMetadata(false, Callback));

    private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var behaviors = Interaction.GetBehaviors(d);

        var eventTriggerBehavior = new EventTriggerBehavior
        {
            EventName = "DoubleTapped"
        };
        eventTriggerBehavior.Actions.Add(new ScrollViewerDoubleTap());

        behaviors.Add(eventTriggerBehavior);
    }
}

关于c# - 行为在 Style Setter 中无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27715798/

相关文章:

c# - 具有搜索模式的 StorageFolder.GetFilesAsync() 方法?

c# - XAML 中 Windows 8 商店应用程序中的 TreeView

c# - LINQ、联接、分组和聚合

c# - 如何防止在类准备就绪之前调用该类的方法?

c# - 不能对空值调用此方法或属性。数据为空

xaml - Windows 8 Metro : Implementing Validation

c++ - WinRT - 没有静态构造函数?

c# - 如何使我的 TextBlocks 在我的 C# XAML Windows 8.1 应用程序中具有正确的大小?

winrt-xaml - 如何在 ContentDialog 中添加可滚动文本? [WP8.1 Win-RT]

c# - Xamarin 从 2.5 更新到 3.5 后,Xamarin.Forms.Platform.Android 不存在