RelativeSource binding can't find Frame ancestor - c#

I'm trying to pass as a CommandParameter the actual Frame object to which I'm applying the Command
XAML
<Frame NavigationUIVisibility="Hidden" Source="{Binding TargetContentPage}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ContentRendered">
<command:EventToCommand Command="{Binding ContentRendered}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Frame}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Frame>
C#
public RelayCommand<Frame> ContentRendered
{
get
{
return new RelayCommand<Frame>(frame => frame.RemoveBackEntry());
}
}
When running, a NullReferenceException is raised saying frame is null.
What is possibly wrong in the code above ?

There is no ancestor/descendent relation between Frame and EventToCommand. Use an ElementName binding instead:
<Frame x:Name="frame" ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="ContentRendered">
<command:EventToCommand
Command="{Binding ContentRendered}"
CommandParameter="{Binding ElementName=frame}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Frame>

Related

Creating audio player on WPF using NAudio. Binding doesn't work

I am creating my audio player on WPF using NAudio.
I am adding a slider that will be scroll the song.
XAML:
<Slider Height="30"
Value="{Binding Path=MediaReader.Position, Mode=TwoWay}"
Maximum="{Binding Path=MediaReader.Length, Mode=OneWay}"/>
Note. MediaReader - it's a property that returns the object of type MediaFoundationReader:
MediaFoundationReader mediaReader;
public MediaFoundationReader MediaReader => mediaReader;
Problem: while the song is plaing the slider property Value doesn't change! But by scrolling the thumb of the slider the property Position of the MediaReader changes.
Why does it work so and how can I solve that?
Just take a look to this tutorial:
https://www.pluralsight.com/guides/building-a-wpf-media-player-using-naudio
The author uses also a slider control and binds the current track position, e.g.:
<Slider Grid.Column="0" Minimum="0" Maximum="{Binding CurrentTrackLenght, Mode=OneWay}" Value="{Binding CurrentTrackPosition, Mode=TwoWay}" x:Name="SeekbarControl" VerticalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding TrackControlMouseDownCommand}"></i:InvokeCommandAction>
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseUp">
<i:InvokeCommandAction Command="{Binding TrackControlMouseUpCommand}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Slider>
public double CurrentTrackPosition
{
get { return _currentTrackPosition; }
set
{
if (value.Equals(_currentTrackPosition)) return;
_currentTrackPosition = value;
OnPropertyChanged(nameof(CurrentTrackPosition));
}
}
I think you can get the idea behind this...

Triggering a command with a command target

*I'm using Material Design though this shouldn't be relative to the question
<ScrollViewer>
<ListView>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
</ScrollViewer>
Sofar I've gotten it to trigger the command on double click, although I want to also set a command target property like:
CommandTarget="{Binding ElementName=addhost}"

WPF Grid: MouseUp event is not fired after mouse move

have discovered that the Mouse up work properly most of the time, they just do not get fired when my mouse has begun moving after the initial click. I have a pretty heavy mouse move event. So the only conclusion i can draw is that the mouse move event is some how preventing the mouse button up event from firing. Any thoughts please.
Note: I am using MVVM model.
<Grid >
<Image x:Name="DynamicJoystickWindow" RenderTransformOrigin="0.5,0.5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseUp" >
<cmd:EventToCommand Command="{Binding JoystickMouseUp_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>
<!--<i:EventTrigger EventName="MouseUp" >
<cmd:EventToCommand Command="{Binding JoystickMouseUp_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>-->
<i:EventTrigger EventName="PreviewMouseDown">
<cmd:EventToCommand Command="{Binding JoystickMouseDown_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseMove" >
<cmd:EventToCommand Command="{Binding JoystickMouseMove_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>
<!--<i:EventTrigger EventName="MouseMove" >
<cmd:EventToCommand Command="{Binding JoystickMouseMove_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>-->
</i:Interaction.Triggers>
<Image.RenderTransform>
<ScaleTransform ScaleX="{Binding RenderScaleTransform}" ScaleY="{Binding RenderScaleTransform}"/>
</Image.RenderTransform>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Resources/transparent.png"/>
<Setter Property="Opacity" Value="0.3" />
</Style>
</Image.Style>
</Image>
</Grid>
I do not observe the behavior you describe, so I would suggest you to simplify your problem to understand what's going on.
For example, remove your image and work only with the grid to see if something change.
I used the following code and it works well for me:
<Grid x:Name="DynamicJoystickWindow" RenderTransformOrigin="0.5,0.5" Background="Blue">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseUp" >
<command:EventToCommand Command="{Binding JoystickMouseUp_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseDown">
<command:EventToCommand Command="{Binding JoystickMouseDown_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseMove" >
<command:EventToCommand Command="{Binding JoystickMouseMove_Dynamic}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>
The only case where event is not fired is when I finish my move outside of the grid.
Hope it helps.
Thanks guys. Problem is, I had the image size smaller than the grid. as #Ouarzy suggested, had grid only and tried. the mouse events works as expected.

Treeview selectedItem highlight on startup

I have a treeview in my xaml as below. I use the selected item by using interactivity and bind the event.
<DataTemplate x:Key="TreeTemplate">
<TreeView Name="TreeView" ItemsSource="{Binding ItemList}" ItemTemplate="{StaticResource ChildTemplate}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction
Command="{Binding SetSelectedItemCommand}"
CommandParameter="{Binding SelectedItem, ElementName=TreeView}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TreeView>
</DataTemplate>
This all works very well except when by application loads for the first time. Even if SelectedItem property is set on startup, the treeview does not show the item highlighted unless a mouse event is fired which causes SelectedItemChanged event.
Any ideas as as to how can I do this?
My datacontext is in code behind of the xaml
myView = new MyViewModel();
this.DataContext = myView;
InitializeComponent();
This will work:
<DataTemplate x:Key="TreeTemplate">
<TreeView Name="TreeView" ItemsSource="{Binding ItemList}" ItemTemplate="{StaticResource ChildTemplate}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction
Command="{Binding SetSelectedItemCommand}"
CommandParameter="{Binding SelectedItem, ElementName=TreeView}"/>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction
Command="{Binding SetSelectedItemCommand}"
CommandParameter="{Binding SelectedItem, ElementName=TreeView}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TreeView>
</DataTemplate>

Button inside the GridSplitter not working WPF MVVM

I put the button inside the gridsplitter. my intention is to make clickable gridsplitter as well as slideable. my problem is after putting button inside the grid splitter, totally cannot drag by mouse. how can i configure the grid splitter to clickable and slideable.
<GridSplitter BorderThickness="1" HorizontalAlignment="Stretch" Grid.Column="1" >
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Grid>
<Button Name="btnSplit" Content="⁞" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding SplitterClickCommand}" CommandParameter="{Binding ElementName=btnSplit}" ></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter>
Best Rgds
df
Try to subscribe MouseDoubleClick event on GridSplitter:
<GridSplitter BorderThickness="1" HorizontalAlignment="Stretch" Grid.Column="1" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding SplitterClickCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</GridSplitter>
If MouseDoubleClick event is not suitable for you, you can try to subscribe to MouseDown or MouseLeftButtonDown.

Categories