I have a requirement to host a control in the content area of a tab control, but display it to the right of the tabs. I though this would be easy with a negative Margin or a RenderLayout. It worked perfectly, until I tried to interact with the control. It's acting as if there is a transparent panel between the tabs and the right margin of the control that still allows the control to be visible, but traps all mouse clicks. If you write a TabControl.MouseDown event handler you can see it being triggered, even when you click on the upper half of the button below.
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:RenderTransformBug"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<TabControl>
<TabItem Header="Tab Item">
<Button Height="30" Width="100" Content="Click me" Cursor="Hand"
VerticalAlignment="Top" Margin="0,-20,0,0"/>
</TabItem>
</TabControl>
</Window>
One solution is to detect when the mouse is over the button and capture the mouse. When the mouse is no longer over the button we need to release the mouse. This means we have to evaluate the location of the mouse whenever it moves. We cannot do this in the CanExecute event handler because that doesn't get called for mouse movements, so we need to write a MouseMove event handler for the window. Take a look at the XAML below and the supporting code.
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:RenderTransformBug"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
MouseMove="Window_MouseMove"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<RoutedCommand x:Key="ClickCommand"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource ClickCommand}" Executed="Click_Executed"/>
</Window.CommandBindings>
<TabControl>
<TabItem Header="Tab Item">
<Button Height="30" Width="100" Content="Click me" Cursor="Hand" Initialized="Button_Initialized"
VerticalAlignment="Top" Margin="0,-20,0,0" Command="{StaticResource ClickCommand}"/>
</TabItem>
</TabControl>
</Window>
public partial class MainWindow : Window
{
Button b;
InitializeComponent();
}
MessageBox.Show("Clicked");
Point P = Mouse.GetPosition(b);
else
b.ReleaseMouseCapture();
}
b = (Button)sender;
}
}
Note that Button.IsMouseOver returns false until the button has captured the mouse so we have to look at the button's coordinates. This now gives us the desired functionality.
No comments:
Post a Comment