Reputation: 3415
I have the following XAML file:
<MediaElement Name="mediaElementOne"
LoadedBehavior="Manual"
Stretch="UniformToFill"
ScrubbingEnabled="True"
MediaOpened="Media_Success"
MediaFailed="Media_Failure"/>
The MediaOpened property currently calls the "Media_Success" when the media loaded successfully.
My issue is with MediaFailed, because I only want MediaFailed to fire on a boolean, meaning I need this to be conditional based on a boolean in my .cs file for the aforementioned XAML file.
How do I write a conditional in a XAML file? Or how would I be able to do this on the .cs file.
Right now as soon as .net believes the media failed it fires the Media_Failure function. I don't want it to fire the Media_Failure function when a specific boolean is set to false and for reasons far outside the scope of this question I can't handle the condition inside of the Media_Failure function.
Additional info: Here is the method it fires on the .cs file:
private void Media_Failure(object sender, ExceptionRoutedEventArgs e){...}
Upvotes: 0
Views: 680
Reputation: 8823
Here is a way to do it(without any extra lib like interactivity etc).
Create a helper class:(which gives you flexibility to write down logic for events and/or behaviors and/or triggers and/or command bindings and/or a middle layer for event handling).
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: (Just set the helper class properties from XAML and this will work with any element.)
<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>
Upvotes: 0
Reputation: 200
You can use triggers.
This code is in reference to winrt xaml. The same can you do in WPF:
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Binding="{Binding IsFailed}" Value="True">
<Core:CallMethodAction MethodName="MediaFailed"/>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
This will go with your media element.
So, if your bool is true it will call a method.
Upvotes: 1
Reputation: 7163
A pattern like this comes to mind where you set or clear the MediaFailed event handler based on the boolean, which you make a property with a 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;
}
}
}
}
You will have to inspire from this pattern and adapt to your code, but this should accomplish what you want.
Edit:
Thought about this more for some reason and arrived at an alternative which is very similar to what Maurice came up with, by using a level of abstraction to solve the problem.
Define a wrapper or the failed event:
MediaFailed="Media_Failure_Wrapper"
Always let this be called, and only call your original event handler when your boolean is true:
private void Media_Failure_Wrapper(object sender, ExceptionRoutedEventArgs e)
{
if (_isMediaFailureEnabled)
{
return Media_Failure(sender, e);
}
else
{
e.Handled = true;
return;
}
}
Upvotes: 0