XAML 文件中的条件

本文关键字:条件 文件 XAML | 更新日期: 2023-09-27 18:32:17

>我有以下 XAML 文件:

<MediaElement Name="mediaElementOne"
              LoadedBehavior="Manual"
              Stretch="UniformToFill"
              ScrubbingEnabled="True"
              MediaOpened="Media_Success"
              MediaFailed="Media_Failure"/>

属性当前在媒体成功加载时调用"Media_Success"。

我的问题与 MediaFailed 有关,因为我只希望 MediaFailed 在布尔值上触发,这意味着我需要根据上述 XAML 文件的.cs文件中的布尔值来有条件地执行此操作。

如何在 XAML 文件中编写条件?或者我如何在.cs文件上执行此操作。

现在,一旦 .net 认为媒体失败了,它就会触发 Media_Failure 函数。当特定布尔值设置为 false 时,我不希望它触发 Media_Failure 函数,并且由于远远超出此问题范围的原因,我无法处理 Media_Failure 函数内部的条件。

附加信息:下面是它在.cs文件上触发的方法:

private void Media_Failure(object sender, ExceptionRoutedEventArgs e){...}

XAML 文件中的条件

您可以使用触发器。

此代码引用了 winrt xaml。在 WPF 中也可以执行相同的操作:

<Interactivity:Interaction.Behaviors>
    <Core:DataTriggerBehavior Binding="{Binding IsFailed}" Value="True">
      <Core:CallMethodAction MethodName="MediaFailed"/>
    </Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>

这将与您的媒体元素一起使用。

所以,如果你的布尔值是真的,它将调用一个方法。

在基于布尔值设置或清除 MediaFailed 事件处理程序的位置中,会想到这样的模式,您可以使用 getter/setter 创建一个属性。

private bool _isMediaFailureEnabled;
public bool isMediaFailureEnabled
{
    get
    {
        return _isMediaFailureEnabled;
    }
    set
    {
        if (_isMediaFailureEnabled != value)
        {
            _isMediaFailureEnabled = value;
            if (_isMediaFailureEnabled)
            {
                mediaElementOne.MediaFailed += MediaElementOne_MediaFailed;
            }
            else
            {
                mediaElementOne.MediaFailed -= MediaElementOne_MediaFailed;
                // OR
                // mediaElementOne.MediaFailed = null;
            }
        }
    }
}

您必须从此模式中汲取灵感并适应您的代码,但这应该可以完成您想要的。

编辑:

出于某种原因,我更多地考虑了这一点,并得出了一个与莫里斯提出的非常相似的替代方案,通过使用抽象级别来解决问题。

定义包装器或失败事件:

MediaFailed="Media_Failure_Wrapper"

始终允许调用它,并且仅在布尔值为 true 时才调用原始事件处理程序:

private void Media_Failure_Wrapper(object sender, ExceptionRoutedEventArgs e)
{
    if (_isMediaFailureEnabled)
    {
        return Media_Failure(sender, e);
    }
    else
    {
        e.Handled = true;
        return;
    }
}

这是一种方法(没有任何额外的库,如交互性等)。

创建一个帮助程序类:(这使您可以灵活地写下事件和/或行为和/或触发器和/或命令绑定和/或事件处理的中间层的逻辑)。

public class RoutedEventTrigger : FrameworkElement
{       
    RoutedEvent _routedEvent;
    public RoutedEvent RoutedEvent
    {
        get { return _routedEvent; }
        set { _routedEvent = value; }
    }
    private Action<object, RoutedEventArgs> handler;
    public Action<object, RoutedEventArgs> Handler
    {
        get { return handler; }
        set { handler = value; }
    }
    public static DataTemplate GetTemplate(DependencyObject obj)
    {
        return (DataTemplate)obj.GetValue(TemplateProperty);
    }
    public static void SetTemplate(DependencyObject obj, DataTemplate value)
    {
        obj.SetValue(TemplateProperty, value);
    }
    public static readonly DependencyProperty TemplateProperty =
        DependencyProperty.RegisterAttached("Template",
        typeof(DataTemplate),
        typeof(RoutedEventTrigger),
        new PropertyMetadata(default(DataTemplate), OnTemplateChanged));
    private static void OnTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DataTemplate dt = (DataTemplate)e.NewValue;
        if (dt != null)
        {
            dt.Seal();
            RoutedEventTrigger ih = (RoutedEventTrigger)dt.LoadContent();
            (d as FrameworkElement).AddHandler(ih.RoutedEvent, new RoutedEventHandler(ih.OnRoutedEvent));                
        }
    }
    void OnRoutedEvent(object sender, RoutedEventArgs args)
    {
        Handler.Invoke(sender, args);
    }
    
} 

XAMl:(只需从 XAML 设置帮助程序类属性,这将适用于任何元素。

<Button Height="100" Width="200" Content="Click" Name="mybutton" >
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsEventAttached}" Value="true">
                    <Setter  Property="local:RoutedEventTrigger.Template">
                        <Setter.Value>
                            <DataTemplate>
                                <local:RoutedEventTrigger RoutedEvent="Button.Click" Handler="MySlider_ValueChanged" />
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>