what about the next solution; try to use Popup.IsOpen property (here is the information about, and here is the example of usage #867 – Controlling Whether a Popup Is Open Using Data Binding ). Bind it to UC1 DataContext directly or via DependencyProperty of CusCtrl user control (you have to create that property in your control that encapsulate the Popup). That's all, this way you will be able to manage popup to be opened or closed without the event.
Update
Try the next:
1. Main Xaml:
<Window x:Class="PopupIsOpenDataBindingHelpAttempt.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:popupIsOpenDataBindingHelpAttempt="clr-namespace:PopupIsOpenDataBindingHelpAttempt"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<popupIsOpenDataBindingHelpAttempt:DemoMainViewModel/>
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="PopupInnerControlDataTemplateKey" DataType="{x:Type popupIsOpenDataBindingHelpAttempt:TaskBarDemoViewModel}">
<Grid Width="150" Height="85">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding TextString}"
Margin="5" Foreground="Red"
Width="150" TextWrapping="WrapWithOverflow"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
<Button Grid.Row="1" Content="Press to close" Command="{Binding PopupInnerButtonCommand}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</Grid>
</DataTemplate>
<Image x:Key="ImageControl" Source="Pic/2015_10_16_Bing_en-US.jpg" IsHitTestVisible="False"/>
</Window.Resources>
<Grid Width="75" Height="75" HorizontalAlignment="Center" VerticalAlignment="Center">
<popupIsOpenDataBindingHelpAttempt:TaskBarIconProjectDemo
ButtonContentProperty="{StaticResource ImageControl}"
ButtonCommandProperty="{Binding ShowPopupCommand}"
PopupIsOpenProperty="{Binding IsPopupOpen, UpdateSourceTrigger=PropertyChanged}"
PopupInnerContentControlDataContext="{Binding TaskBarDemoViewModel, UpdateSourceTrigger=PropertyChanged}"
PopupInnerContentControlContentTemplate="{StaticResource PopupInnerControlDataTemplateKey}"/>
</Grid>
2. Popup encapsulating XAMl:
<UserControl x:Class="PopupIsOpenDataBindingHelpAttempt.TaskBarIconProjectDemo"
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" x:Name="This">
<Grid>
<Button Style="{StaticResource SpecialButtonStyle}" Command="{Binding ElementName=This, Path=ButtonCommandProperty}"
Content="{Binding ElementName=This, Path=ButtonContentProperty}"></Button>
<Popup IsOpen="{Binding ElementName=This, Path=PopupIsOpenProperty}">
<ContentControl Content="{Binding ElementName=This, Path=PopupInnerContentControlDataContext}"
ContentTemplate="{Binding ElementName=This, Path=PopupInnerContentControlContentTemplate}"/>
</Popup>
</Grid>
3. Popup encapsulating control code behind (dependency properties):
public partial class TaskBarIconProjectDemo : UserControl
{
public static readonly DependencyProperty ButtonCommandPropertyProperty = DependencyProperty.Register("ButtonCommandProperty", typeof (ICommand), typeof (TaskBarIconProjectDemo), new PropertyMetadata(default(ICommand)));
public static readonly DependencyProperty PopupIsOpenPropertyProperty = DependencyProperty.Register("PopupIsOpenProperty", typeof (bool), typeof (TaskBarIconProjectDemo), new PropertyMetadata(default(bool)));
public static readonly DependencyProperty PopupInnerContentControlDataContextProperty = DependencyProperty.Register("PopupInnerContentControlDataContext", typeof (object), typeof (TaskBarIconProjectDemo), new PropertyMetadata(default(object)));
public static readonly DependencyProperty PopupInnerContentControlContentTemplateProperty = DependencyProperty.Register("PopupInnerContentControlContentTemplate", typeof (DataTemplate), typeof (TaskBarIconProjectDemo), new PropertyMetadata(default(DataTemplate)));
public static readonly DependencyProperty ButtonContentPropertyProperty = DependencyProperty.Register("ButtonContentProperty", typeof (object), typeof (TaskBarIconProjectDemo), new PropertyMetadata(default(object)));
public TaskBarIconProjectDemo()
{
InitializeComponent();
}
public ICommand ButtonCommandProperty
{
get { return (ICommand) GetValue(ButtonCommandPropertyProperty); }
set { SetValue(ButtonCommandPropertyProperty, value); }
}
public bool PopupIsOpenProperty
{
get { return (bool) GetValue(PopupIsOpenPropertyProperty); }
set { SetValue(PopupIsOpenPropertyProperty, value); }
}
public object PopupInnerContentControlDataContext
{
get { return (object) GetValue(PopupInnerContentControlDataContextProperty); }
set { SetValue(PopupInnerContentControlDataContextProperty, value); }
}
public DataTemplate PopupInnerContentControlContentTemplate
{
get { return (DataTemplate) GetValue(PopupInnerContentControlContentTemplateProperty); }
set { SetValue(PopupInnerContentControlContentTemplateProperty, value); }
}
public object ButtonContentProperty
{
get { return (object) GetValue(ButtonContentPropertyProperty); }
set { SetValue(ButtonContentPropertyProperty, value); }
}
}
4. View Models:
public class DemoMainViewModel:BaseObservableObject
{
private bool _isOpen;
private TaskBarDemoViewModel _taskBarDemoViewModel;
private ICommand _showPopupCommnad;
public DemoMainViewModel()
{
TaskBarDemoViewModel = new TaskBarDemoViewModel(ClosePopup, "Here you can put your content. Go for it...");
}
private void ClosePopup()
{
IsPopupOpen = false;
}
public bool IsPopupOpen
{
get { return _isOpen; }
set
{
_isOpen = value;
OnPropertyChanged();
}
}
public TaskBarDemoViewModel TaskBarDemoViewModel
{
get { return _taskBarDemoViewModel; }
set
{
_taskBarDemoViewModel = value;
OnPropertyChanged();
}
}
public ICommand ShowPopupCommand
{
get { return _showPopupCommnad ?? (_showPopupCommnad = new RelayCommand(ShowPopup)); }
}
private void ShowPopup()
{
IsPopupOpen = true;
}
}
public class TaskBarDemoViewModel:BaseObservableObject
{
private readonly Action _closePopupCommand;
private ICommand _command;
private string _textString;
public TaskBarDemoViewModel(Action closePopupCommand, string content)
{
_closePopupCommand = closePopupCommand;
TextString = content;
}
public ICommand PopupInnerButtonCommand
{
get { return _command ?? (_command = new RelayCommand(TargetMethod)); }
}
private void TargetMethod()
{
//add your logic here
if(_closePopupCommand == null) return;
_closePopupCommand();
}
public string TextString
{
get { return _textString; }
set
{
_textString = value;
OnPropertyChanged();
}
}
}
5. Button style (change this as your need):
<Color x:Key="ButtonLowerPartKey">#FFD5E0EE</Color>
<Color x:Key="ButtonUpperPartKey">#FFEAF1F8</Color>
<Color x:Key="PressedColorButtonLowerPartKey">#FFF4C661</Color>
<Color x:Key="PressedButtonUpperPartKey">#FFF4CC87</Color>
<Color x:Key="HooveredButtonLowerPartKey">#FFFFD06D</Color>
<Color x:Key="HooveredButtonUpperPartKey">#FFFFF0DF</Color>
<Style x:Key="SpecialButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Padding" Value="5">
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid x:Name="Grid">
<Ellipse x:Name="ButtonControlBorder" Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="{TemplateBinding BorderThickness}"
Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Ellipse.Fill>
<LinearGradientBrush x:Name="BrushKey" MappingMode="RelativeToBoundingBox" SpreadMethod="Repeat" StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.5" Color="{StaticResource ButtonUpperPartKey}" />
<GradientStop Offset="0.5" Color="{StaticResource ButtonUpperPartKey}" />
<GradientStop Offset="0.5" Color="{StaticResource ButtonLowerPartKey}" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="Pressed" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Opacity="0">
<Ellipse.Fill>
<LinearGradientBrush x:Name="PressedBrushKey" MappingMode="RelativeToBoundingBox" SpreadMethod="Repeat" StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.5" Color="{StaticResource PressedButtonUpperPartKey}" />
<GradientStop Offset="0.5" Color="{StaticResource PressedButtonUpperPartKey}" />
<GradientStop Offset="0.5" Color="{StaticResource PressedColorButtonLowerPartKey}" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="InnerPressed"
Width="{Binding ElementName=Pressed, Path=Width}" Height="{Binding ElementName=Pressed, Path=Height}"
Stroke="DarkOrange" Opacity="0" StrokeThickness="1" SnapsToDevicePixels="True" Fill="Transparent"/>
<ContentPresenter Content="{TemplateBinding Button.Content}" HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.OpacityMask>
<VisualBrush Visual="{Binding ElementName=ButtonControlBorder}" />
</ContentPresenter.OpacityMask>
</ContentPresenter>
<Grid.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard x:Name="MouseEnterStoryboard">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BrushKey" Storyboard.TargetProperty="GradientStops[0].Color" From="{StaticResource ButtonUpperPartKey}" To="{StaticResource HooveredButtonUpperPartKey}" Duration="0:0:0.3" AutoReverse="False" />
<ColorAnimation Storyboard.TargetName="BrushKey" Storyboard.TargetProperty="GradientStops[2].Color" From="{StaticResource ButtonLowerPartKey}" To="{StaticResource HooveredButtonLowerPartKey}" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="BrushKey" Storyboard.TargetProperty="GradientStops[0].Color" From="{StaticResource HooveredButtonUpperPartKey}" To="{StaticResource ButtonUpperPartKey}" Duration="0:0:1" AutoReverse="False" />
<ColorAnimation Storyboard.TargetName="BrushKey" Storyboard.TargetProperty="GradientStops[2].Color" From="{StaticResource HooveredButtonLowerPartKey}" To="{StaticResource ButtonLowerPartKey}" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="MouseUpTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Pressed" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MouseDownTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Pressed" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.05" Value="0.8" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="InnerPressedMouseUpTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="InnerPressed" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="InnerPressedMouseDownTimeLine">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="InnerPressed" Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="00:00:00.05" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" SourceName="Grid" Value="True">
<Setter Property="Stroke" TargetName="ButtonControlBorder">
<Setter.Value>
<SolidColorBrush Color="{StaticResource HooveredButtonLowerPartKey}">
</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ButtonBase.IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MouseDownTimeLine}" />
<BeginStoryboard Storyboard="{StaticResource InnerPressedMouseDownTimeLine}">
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource MouseUpTimeLine}" />
<BeginStoryboard Storyboard="{StaticResource InnerPressedMouseUpTimeLine}">
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
BaseObservableObject is the simple implementation of INCP.
RelayCommand is the simple implementation of ICommand interface.
I'll glad to help if you will have the problem with the code.
Regards,