Event Binding doesn't work in ContentPresenter - c#

I'm want to use Interaction.Triggers inside a ContentPresenter, but for some reasons, the event doesn't get fired.
If I change ContentPresenter against ContentControl, the event binding works as expected.
<DataTemplate x:Key="MapPictureTemplate">
<Grid Width="80" Height="80" x:Name="Grid">
<Border
Background="{Binding Thumbnail, Converter={StaticResource StreamToImageBrushConverter}}"
CornerRadius="40">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<i:InvokeCommandAction Command="{Binding Source={StaticResource Locator}, Path=Main.ImageTappedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Border>
</Grid>
</DataTemplate>
and the ContentControl creation in code behind:
var content = new ContentPresenter()
{
Content = this,
ContentTemplate = Application.Current.Resources["MapPictureTemplate"] as DataTemplate
};

Related

How to define a Command as a StaticResource WPF

I am trying to bind a to a command defined in the DataContext of the xaml in a DataGridColumn, however I cannot use RelativeSource as columns are not part of the hierarchy, so my current solution is so define the command in the ResourceDictionary and reference it.
However my problem is I can't seem to find how to define an ICommand in the ResourceDictionary, how can I do this? Or any other ways to access my command in DataContext from a DataGridColumn ?
xmlns:input="clr-namespace:System.Windows.Input;assembly=System"
...
<UserControl.Resources>
<ResourceDictionary>
<input:ICommand x:Key="propertyChangedEvent">
"{Binding PropertyChangedEvent}"
</input:ICommand>
</ResourceDictionary>
</UserControl.Resources>
...
<DataGridTemplateColumn Header="Notes" MinWidth="350" Width="*" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Margin="1">
<TextBox Text="{Binding Notes, UpdateSourceTrigger=LostFocus}" BorderThickness="0" AcceptsReturn="True" TextWrapping="Wrap" >
<i:Interaction.Triggers >
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{StaticResource propertyChangedEvent}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Try to use Element Binding by providing element name whose has the DatacContext.
<i:InvokeCommandAction Command="{Binding ElementName=Window1, Path=DataContext.CommandPropertyName}" />

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.

How to get parent event inside ControlTemplate?

I want to invoke a Command from view model inside radio button ControlTemplate. And do it when event Checked is raised
I tried this:
<ControlTemplate x:Key="RequestTypeControlTemplate" TargetType="RadioButton">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,0,2">
<ContentPresenter Margin="10,0,10,0">
<i:Interaction.Triggers>
<!-- Checked event from parent -->
<i:EventTrigger EventName="Checked">
<!-- Command from view model and binding to tag of radio button as arg -->
<i:InvokeCommandAction Command="{Binding DataContext.OnTypeChangedCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ContentPresenter>
</Border>
</ControlTemplate>
But I think event goes from ContentPresenter, not from RadioButton. How do I get the event from RadioButton?
EDIT:
<RadioButton Content="All requests"
ContentTemplate="{StaticResource RadioButtonDataTemplate}"
GroupName="Filter"
IsChecked="True"
Style="{StaticResource RadioButtonStyle}"
Template="{StaticResource RequestTypeControlTemplate}"
Tag="{x:Static local:ContentType.Any}"/>
In viewModel
public ICommand OnTypeChangedCommand
{
get
{
return m_TypeChangedCommand ?? (m_TypeChangedCommand = new DelegateCommand<ContentType>(OnTypeChanged));
}
}
public void OnTypeChanged(ContentType type)
{
Debug.WriteLine(type);
}
You can't do that because the Routed event is only handled from the element (bubble) or to the element (tunnel)
What you can use is a DataTrigger on IsChecked property .
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding IsChecked,RelativeSource={RelativeSource AncestorType=RadioButton}}" Value=True>
<i:InvokeCommandAction Command="{Binding DataContext.OnTypeChangedCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource AncestorType=RadioButton}}}" />
</ei:DataTrigger>
</i:Interaction.Triggers>

How can i bind a button in listviewitem to a Command in ViewModel in Winrt

I have a NavigateToAccountsCommand RelayCommand property in the ViewModel. When I bind the same to a button on the page anywhere outside the ListView the command binding is working. However as soon as I move this to a ListView's DataTemplate its not working.
I have tried changing the binding from NavigateToAccountsCommand to DataContext.NavigateToAccountsCommand still not working.
Appreciate your help...
<Page
x:Class="FinancePRO.App.Views.AccountsView"
DataContext="{Binding AccountsViewModel, Source={StaticResource MainViewModelLocator}}"
mc:Ignorable="d">
<Grid>
<!--**This one is working**-->
<Button Command="{Binding NavigateToAccountsCommand}" >
<!--**This one is not working**-->
<ListView ItemsSource="{Binding AllAccounts}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding AccountName}"/>
<Button Command="{Binding NavigateToAccountsCommand}">
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When you are inside the DataTemplate of the ListView, your data context is the current item of the ListView's ItemsSource. As there is nothing called "NavigateToAccountsCommand" property within your AllAcounts' each individual element, binding isn't working.
To fix that, you will need to reference something from the outside of DataTemplate; following should work. It changes the binding to reference the root Grid's DataContext which should have the property NavigateToAccountsCommand accessible. To reference the grid, you have to add Name attribute, and then use ElementName binding.
<Grid Name="Root">
<!--**This one is working**-->
<Button Command="{Binding NavigateToAccountsCommand}" >
<!--**This one is not working**-->
<ListView ItemsSource="{Binding AllAccounts}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding AccountName}"/>
<Button Command"{Binding ElementName=Root, Path=DataContext.NavigateToAccountsCommand}">
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
You can use
<Button x:Name="cmdTabItemCloseButton"
Style="{StaticResource TabItemCloseButtonStyle}"
Grid.Column="1" Margin="15,0,0,0"
Command="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type ListView}},
Path=DataContext.NavigateToAccountsCommand}"
CommandParameter="{Binding}"/>
I had a similar problem (Win RT) which I solved by just using:
<GridView
x:Name="itemGridView"
ItemClick="ItemView_ItemClick"
IsItemClickEnabled="True"/>
and then in the Page class:
private void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
//e is the object being clicked
}

WPF ListBox selection

I have a problem with extended selection in ListBox. Let's say I have a ListBox with 10 items and I'm selecting first 5 of them using Shift button. The SelectionChanged event is fired with 5 items. After that I want to select 3 items from those 5, again with Shift button pressed, but SelectionChanged event is not fired. How can I react to the second selection of items, when I'm selecting 3 of those 5 previously selected ones?
can you show the xaml code as well I would like to see what your binding looks like
it should looks something like this.. but I can't be certain unless I see your code
In Command binding you have used binding which has relative source binding...
consider making these changes in binding
1) using list box as Ancestortype
2) While binding use Path=DataContext.SelectionChangedCommand otherwise it will take list box as datacontext.
<catel:EventToCommand Command="{Binding Path=DataContext.SelectionChangedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" DisableAssociatedObjectOnCannotExecute="False" PassEventArgsToCommand="True" />
here is an example of what the XAML would look like for ListBoxItem Template
<Grid>
<StackPanel Orientation="Horizontal">
<Label Width="180">Field1</Label>
<ListBox Height="200"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding List1, Mode=OneWay}"
Name="listBox1"
SelectionMode="Single"
Width="300">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Width="290">
<TextBlock Width="90" Text="{Binding}"></TextBlock>
<ComboBox Width="180" ItemsSource="{Binding DataContext.List2, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" DisplayMemberPath="Field1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<catel:EventToCommand Command="{Binding Path=DataContext.SelectionChangedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" DisableAssociatedObjectOnCannotExecute="False" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>

Categories