Reputation: 340
I have the following user control xaml
<UserControl x:Class="tgltestpopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Popup IsOpen="{Binding ElementName=tgl,Path=IsChecked}" StaysOpen="False">
<Border Background="White">
<StackPanel>
<Button Click="showMsgEvent" Content="close"></Button>
<Button Content="test me" Command="{Binding showMsgCommand,RelativeSource={RelativeSource AncestorType=UserControl}}"></Button>
</StackPanel>
</Border>
</Popup>
<ToggleButton Content="open popup" x:Name="tgl" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
this user control is used inside a datagrid Template column . How ever when i click the toggle button the popup displays but the buttons not respond to the events or commands . The buttons are highlighted when the mouse pass over them but when i click them do nothing!.even when i press the button the button state dose not change . Looks like don't recognize the button that i clicked it.
Any suggestion?
Upvotes: 2
Views: 1158
Reputation: 2620
I got this working by using an EventTrigger
and PreviewMouseDown
. For some reason, MouseDown
is not working and i think this is the reason the simple command fails too. Maybe the focus is changing and the button is not really clicked in fact.
But anyway, here is what I came up with:
<Window x:Class="TestPopupInDataTemplate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestPopupInDataTemplate"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding Source}"
CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="First">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:TestUserControl/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
To get over it fast, i didn't add a separate view model for the Window:
public partial class MainWindow : Window
{
public ObservableCollection<TestViewModel> Source { get; set; }
public MainWindow()
{
InitializeComponent();
Source = new ObservableCollection<TestViewModel>() { new TestViewModel() { Name = "Test Name11" } };
this.DataContext = this;
}
}
Here is UserControl
which is set on the DataTemplate
:
<UserControl x:Class="TestPopupInDataTemplate.TestUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TestPopupInDataTemplate"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="GridName">
<ToggleButton Content="open popup" x:Name="tgl" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Popup IsOpen="{Binding ElementName=tgl,Path=IsChecked}"
StaysOpen="False" >
<Border Background="White">
<StackPanel>
<!--<Button Click="showMsgEvent" Content="close"></Button>-->
<Button Content="{Binding Name}"
Margin="5"
Width="90"
Height="30"
FontSize="20" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding ShowMsgCommand}"
CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
</Border>
</Popup>
</Grid>
Its view model :
public class TestViewModel
{
public ICommand ShowMsgCommand { get; set; }
public string Name { get; set; }
public TestViewModel()
{
ShowMsgCommand = new OpenMsgCommand(this);
}
public void OpenMessage()
{
Console.WriteLine("test");
}
}
And the command:
public class OpenMsgCommand : ICommand
{
private TestViewModel _vm;
public OpenMsgCommand(TestViewModel vm)
{
_vm = vm;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_vm.OpenMessage();
}
}
Here is the result:
As you see, both the command and command parameter are working as expected.
You need to add a reference to System.Windows.Interactivity in order to use Interaction.Triggers
.
Upvotes: 1