wpf canvas add element from resources - wpf

I am new to wpf
<Window.Resources>
<Ellipse x:Key="connectorNode" Height="20" Width="20" Fill="Green" Stroke="Black" StrokeThickness="2" MouseMove="Ellipse_MouseMove" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown" MouseLeftButtonUp="Ellipse_MouseLeftButtonUp"></Ellipse>
</Window.Resources>
How can i add an instance of the Ellipse in the resources to a canvas, i only want to specify Canvas.Left and Canvas.Right but use the same property values as in resources
<Canvas>
</Canvas>

It seems like you want to create a generic style and apply it to every Ellipse added, this is how you can do it:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="EllipseStyle" TargetType="Ellipse">
<Setter Property="Height" Value="20"/>
<Setter Property="Width" Value="20" />
<EventSetter Event="Control.MouseMove" Handler="Control_MouseMove" />
</Style>
</Window.Resources>
<Grid>
<Canvas>
<Ellipse Style="{StaticResource EllipseStyle}" />
</Canvas>
</Grid>
</Window>
Edit: I've added "EventSetter" so your events can be defined in the style (see this post).

If you really want to use an element from resources and apply only canvas properties you can do it this way:
<Window.Resources>
<ControlTemplate x:Key="connectorNode" >
<Ellipse
Height="20"
Width="20"
Fill="Green"
Stroke="Black"
StrokeThickness="2"
MouseMove="Ellipse_MouseMove"
MouseLeftButtonDown="Ellipse_MouseLeftButtonDown"
MouseLeftButtonUp="Ellipse_MouseLeftButtonUp" />
</ControlTemplate>
</Window.Resources>
<Canvas>
<ContentControl Template="{StaticResource connectorNode}"/>
<ContentControl Canvas.Left="50" Template="{StaticResource connectorNode}"/>
</Canvas>

Related

WPF Can't Remove Red Border from UserControl

I've built a simple login page and when invalid input is detected, a red border is drawn around the usercontrol.
Here is my layout code:
<UserControl x:Class="WPFTest.UI.Views.EmptyLayout"
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:WPFTest.UI.Views"
xmlns:vm="clr-namespace:WPFTest.UI.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance Type=vm:EmptyLayoutViewModel}"
Background="White"
>
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="20" FontWeight="Bold">Test Sales Estimator</TextBlock>
<ContentControl Content="{Binding Layout}" Grid.Row="1">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type vm:LoginViewModel}">
<local:LoginView/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>
</UserControl>
And here is the login view:
<UserControl
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:WPFTest.UI.Views" xmlns:viewmodels="clr-namespace:WPFTest.UI.ViewModels"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" x:Class="WPFTest.UI.Views.LoginView"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Background="White"
d:DataContext="{d:DesignInstance Type={x:Type viewmodels:LoginViewModel}}"
Margin="20 0 0 0"
Padding="10"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="2" Margin="0 50 0 0">
<TextBlock Text="Welcome" FontSize="17" Grid.Row="1" Margin="0 0 0 20" Height="50"/>
<StackPanel>
<TextBlock Text="Username" />
<TextBox Text="{Binding Username}"/>
</StackPanel>
<StackPanel Grid.Row="2" Margin="0 10 0 0">
<TextBlock Text="Password" />
<PasswordBox x:Name="Password" PasswordChanged="PasswordBox_PasswordChanged" >
</PasswordBox>
</StackPanel>
<Button
Grid.Row="2"
Margin="0 20 0 0"
Padding="5 2"
HorizontalAlignment="Left"
Command="{Binding HandleLoginCommand}"
IsEnabled="{Binding CanLogin}"
Content="Login">
</Button>
</StackPanel>
</Grid>
</UserControl>
I have tried to override the border with the following template:
<Style TargetType="views:LoginView">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
But the border remains red. I've also tried changing the target on the template to things like UserControl, and ContentControl. I've also tried setting the Validation.ErrorTemplate attribute to {x:Null} on both the UserControl and on the element inside the layout usercontrol.
For the LoginViewModel, I am using the CommunityToolkit.Mvvm's ObservableValidator as my base class, so it handles the validation logic and here is my Username property.
private string _username;
[Required]
[MinLength(4)]
public string Username
{
get { return _username; }
set {
SetProperty(ref _username, value, true);
OnPropertyChanged(nameof(HandleLoginCommand));
}
}
The border is from your contentcontrol.
Set Validation.ErrorTemplate="{x:Null}" on that.
You can just use a contentpresenter.
<ContentPresenter Content="{Binding Layout}" Grid.Row="1"
Validation.ErrorTemplate="{x:Null}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type local:LoginViewModel}">
<local:LoginView/>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
I have a simplified layout to explore this, but the outer red border does not appear when I make that change.
The validation decoration does not use the control's Border(Thcikness/Brush). It is instead a separate Visual that is drawn in a separate AdornerLayer. To modify its looks, you should pass a dedicated template for the ErrorTemplate like this: (example for TextBox)
<Style TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<Border BorderBrush="Yellow" BorderThickness="3">
<AdornedElementPlaceholder x:Name="AdornedElementPlaceholder" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To actually remove the border, try setting Validation.ErrorTemplate to {x:Null}.

Is it possible to change properties of a resource instantiated with StaticResource element in XAML?

With this piece of XAML:
<Window.Resources>
<Rectangle x:Key="rectangle" x:Shared="False" Width="20" Height="8" Fill="Red" />
</Window.Resources>
<StaticResource x:Name="r1" ResourceKey="rectangle" />
<StaticResource x:Name="r2" ResourceKey="rectangle" />
it is possible to assign a value to say, Margin property, to each instance independently by code:
r1.Margin = 2;
r2.Margin = 5;
Is it possible to do it directly in XAML? I tried:
<StaticResource ResourceKey="rectangle" Margin="3"/>
but Margin is not a property of StaticResource...
Rephrasing after the XY problem sensor fired (appropriately)!
I want to draw rectangles with exactly the same properties except one, e.g. the margin or the color, in order to be able to change the shared properties centrally and still be able to provide specific properties in XAML. Can I use a resource like in my attempt?
Adding my exact need and code as suggested by comments
My exact need is to show the effect of setting different properties to some rectangle, i.e. changing Rectangle.RenderTransformOrigin and Rectangle.RenderTransform to compare effects. It's indeed to learn WPF, not for a production application. At the moment, I use a style (rotated) as I wasn't able to use a resource (this is the reason of my question above).
<Window x:Class="Test.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:Test"
mc:Ignorable="d"
Title="Transform Center" Height="400" Width="600">
<Window.Resources>
<Style x:Key="title" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="Margin" Value="0,0,0,10" />
</Style>
<Style x:Key="rotated" TargetType="Rectangle">
<Setter Property="Width" Value="201" />
<Setter Property="Height" Value="81" />
<Setter Property="Fill" Value="CadetBlue"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style x:Key="fixed" TargetType="Rectangle">
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="Fill" Value="Indigo" />
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Window.Resources>
<Grid >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}" />
</StackPanel>
<TextBlock Grid.Row="0" Grid.Column="0"
Style="{StaticResource title}" Text="No rotation" />
<StackPanel Grid.Row="0" Grid.Column="1" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}">
<Rectangle.RenderTransformOrigin>.5,.5</Rectangle.RenderTransformOrigin>
<Rectangle.RenderTransform>
<RotateTransform Angle="20" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
<TextBlock Grid.Row="0" Grid.Column="1"
Style="{StaticResource title}"
Text="RenderTransformOrigin" />
<StackPanel Grid.Row="1" Grid.Column="0" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}">
<Rectangle.RenderTransform>
<RotateTransform Angle="20" CenterX="100" CenterY="40" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="0"
Style="{StaticResource title}"
Text="RotateTransform Center" />
<!-- The center coordinates relative to the Rectangle are the sum
of both center coordinates, i.e. .5 + .5 = 1 (bottom-right corner) -->
<StackPanel Grid.Row="1" Grid.Column="1" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}">
<Rectangle.RenderTransformOrigin>.5,.5</Rectangle.RenderTransformOrigin>
<Rectangle.RenderTransform>
<RotateTransform Angle="20" CenterX="100" CenterY="40" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="1"
Style="{StaticResource title}"
Text="Both" />
</Grid>
</Window>
Does XAML allows to change a property of a resource when it is instantiated with <StaticResource>
Short answer: No.
The StaticResource markup extension simply references a resource based on a key. It can't change any properties of the resolved resource. You will have to set the properties of the resolved resource itself by for example casting the target property of the resource to a Rectangle.
I want to draw rectangles with exactly the same properties except one, e.g. the margin or the color
That sounds like a style to me. In WPF, there are usually several different ways to accomplish the same thing, and this is no exception.
it seems setting up a view-model is a bit oversized
Maybe. Maybe not. It's hard to say, as there aren't any other details in your question. That said, given the problem statement above, I'd agree it's certainly not necessary, and absent any other requirements, I don't see anything to be gained by using view models.
Even so, here's a code example that shows three different ways, two of which are based on view models and templates:
<Window x:Class="TestSO58683029RectStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:p="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:l="clr-namespace:TestSO58683029RectStyle"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<l:MainViewModel>
<l:MainViewModel.Rectangle1>
<l:RectangleViewModel Margin="2"/>
</l:MainViewModel.Rectangle1>
<l:MainViewModel.Rectangle2>
<l:RectangleViewModel Margin="5"/>
</l:MainViewModel.Rectangle2>
</l:MainViewModel>
</Window.DataContext>
<Window.Resources>
<p:Style TargetType="Rectangle">
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="8"/>
<Setter Property="Fill" Value="Red"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</p:Style>
<DataTemplate DataType="{x:Type l:RectangleViewModel}">
<Rectangle Width="20" Height="8" Fill="Red" HorizontalAlignment="Left" Margin="{Binding Margin}"/>
</DataTemplate>
<x:Array x:Key="rectangleArray1" Type="{x:Type l:RectangleViewModel}">
<l:RectangleViewModel Margin="2"/>
<l:RectangleViewModel Margin="5"/>
</x:Array>
</Window.Resources>
<StackPanel>
<!-- Uses style -->
<Rectangle/>
<Rectangle Margin="2"/>
<Rectangle Margin="5"/>
<!-- Uses view models, individual properties -->
<ContentControl Content="{Binding Rectangle1}"/>
<ContentControl Content="{Binding Rectangle2}"/>
<!-- Uses view models, collection -->
<ItemsControl ItemsSource="{StaticResource rectangleArray1}"/>
</StackPanel>
</Window>
The view model approaches rely on these classes (they don't implement INotifyPropertyChanged, because there's no need in this simple example):
class RectangleViewModel
{
public Thickness Margin { get; set; }
}
class MainViewModel
{
public RectangleViewModel Rectangle1 { get; set; }
public RectangleViewModel Rectangle2 { get; set; }
}
As you can see, in the case of the style-based approach, a single <Style/> element in the resource dictionary can be used to define the default values for any properties you like. Then you can explicitly use a <Rectangle/> element where you want it in the content of your window, setting any other property explicitly. You can even override properties that were set in the style, if that's needed for any reason.
Note that in the above, the data template explicitly sets its property values. But you can actually combine the two techniques, by referring to the style resource when you declare the template, like so:
<DataTemplate DataType="{x:Type l:RectangleViewModel}">
<Rectangle Margin="{Binding Margin}" Style="{StaticResource ResourceKey={x:Type Rectangle}}"/>
</DataTemplate>
As noted in the comments, declaring concrete UI elements as resources is generally the wrong way to do something in WPF. I hesitate to say it's always wrong, but I would say it's almost always wrong. Concrete UI elements should be declared as actual content in the XAML, with styles used to provide default formatting for those elements. Otherwise you should be using templates, and allow WPF to create the UI elements as needed, based on the template you provide.

I want to put a close button in app.xaml window content template in wpf

I have created custom template of target type window now i want that whenever i declare the template the button automatically arrives as a close button on top right corner to close the window but in code of app.xaml i am not getting any idea to perform form closing handler on button click.
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="MyWindowStyle" TargetType="Window">
<Setter Property="WindowStyle" Value="None"></Setter>
<Setter Property="Background" Value="#FFCDFF"></Setter>
<Setter Property="WindowState" Value="Maximized"></Setter>
</Style>
<ControlTemplate TargetType="Window" x:Key="WindowTemplate">
<AdornerDecorator>
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Control x:Name="FocusCatcher"></Control>
<TextBlock Text="Menu Section" HorizontalAlignment="Center"/>
<Button Content="X" FontFamily="Tahoma" Width="25" HorizontalAlignment="Right"></Button>
<ContentPresenter Grid.Row="1" />
<StatusBar Height="23" VerticalAlignment="Bottom" Grid.Row="2">
<TextBlock Text="Current Editing Mode" />
</StatusBar>
</Grid>
</AdornerDecorator>
</ControlTemplate>
</Application.Resources>
And In Mainwindow.xaml
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Style="{StaticResource MyWindowStyle}" Template="{StaticResource WindowTemplate}">
<Grid>
</Grid>
The Form Looks Somehow like this :
if I get you right you want on button click window to close?
then add some extra to your button xaml:
<Button x:Name="someName" Content="X" FontFamily="Tahoma" Width="25" HorizontalAlignment="Right" Click="someName_Click"></Button>
and implement in the code
Private Sub someName_Click(sender As Object, e As EventArgs) Handles someName.Click End Sub
to close it.

Trouble with setting both DataTemplate and ControlTemplate to Map Pushpins in WPF

I am having trouble setting both DataTemplate and ControlTemplate to my bing map pushpins. I am using data binding which works to a point when i try to customize my pushpins by adding ControlTemplate.
My code:
<UserControl x:Class="BingMap.MapUserControl"
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:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
xmlns:viewPushpins="clr-namespace:Program.Map_Control.ViewPushpins">
<UserControl.DataContext>
<viewPushpins:MapViewPushpins/>
</UserControl.DataContext>
<UserControl.Resources>
<DataTemplate x:Key="PushpinDataTemplateP">
<m:Pushpin Location = "{Binding MapLocationP}" ToolTip="{Binding MapTooltipTextP}"/>
</DataTemplate>
<ControlTemplate x:Key="PushpinControlTemplateP">
<Grid>
<Ellipse Fill="Green" Width="15" Height="15" />
</Grid>
</ControlTemplate>
</UserControl.Resources>
<Grid>
<m:Map Name="myMap"
CredentialsProvider="..."
ZoomLevel="1"
Center="30,-100"
Mode="AerialWithLabels"
MouseLeftButtonUp="Map_Left_Click_Up">
<m:MapItemsControl
Template="{StaticResource PushpinControlTemplateP}"
ItemTemplate="{StaticResource PushpinDataTemplateP}" MouseLeftButtonUp="Map_Left_Click_Up"
ItemsSource="{Binding MapLocationsP}"/>
</m:Map>
</Grid>
</UserControl>
This code works if I remove the line:
Template="{StaticResource PushpinControlTemplateP}"
but then don't get my customized pushpin.
Any ideas on how can I fix this?
By setting MapItemsControl.Template, you're specifying a template for the MapItemsControl itself, not the items it produces. You can set the template for individual items produced by an ItemsControl indirectly via the ItemContainerStyle:
<Style x:Key="PushPinStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<!-- your template goes here -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<m:MapItemsControl ItemContainerStyle="{StaticResource }" ...>
I see where i got this wrong. As already mentioned by Kent, the line
Template="{StaticResource PushpinControlTemplateP}"
shouldn't be in MapItemsControl.
I solved my problem with moving this line of code to Resources so they look like this:
<UserControl.Resources>
<ControlTemplate x:Key="PushpinControlTemplateP">
<Grid>
<Ellipse Fill="Green" Width="15" Height="15" />
</Grid>
</ControlTemplate>
<DataTemplate x:Key="PushpinDataTemplateP">
<m:Pushpin Location = "{Binding MapLocationP}" ToolTip="{Binding MapTooltipTextP}" Template="{StaticResource PushpinControlTemplateP}"/>
</DataTemplate>
</UserControl.Resources>

WPF - Binding IsMouseOver to Visibility

I have a window which overrides a RadioButton's ControlTemplate to show a custom control inside of it. Inside the custom control, I have a button's visibility tied to IsMouseOver, which works correctly in showing the button only when the mouse is hovering over the control. However, when I click on the RadioButton, the Button disappears. After some debugging and reading, it seems that the RadioButton is capturing the mouse on click, and this makes IsMouseOver for the UserControl false.
I tried binding the Button's visibility to FindAncestor {x:Type RadioButton} and it works, but it seems a bit fragile to me to have the UserControl depend on who is containing it. The code for the window and the user control is below. Any suggestions?
<Window x:Name="window" x:Class="WPFTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WPFTest="clr-namespace:WPFTest"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<WPFTest:TestUC />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border BorderBrush="Black" BorderThickness="2">
<StackPanel>
<RadioButton x:Name="OptionButton" Height="100" />
<TextBlock Text="{Binding ElementName=OptionButton, Path=IsMouseOver}" />
</StackPanel>
</Border>
</Window>
<UserControl x:Name="_this" x:Class="WPFTest.TestUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>
<StackPanel>
<TextBlock Text="SomeText" />
<TextBlock Text="{Binding ElementName=_this, Path=IsMouseOver}" />
<Button x:Name="_cancelTextBlock" Content="Cancel" Visibility="{Binding ElementName=_this, Path=IsMouseOver, Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
</UserControl>
After the event is handled by the RadioButton , it is only set as handled but in reality it still bubbles up. So you just need to specify that you want to handle handled events too.
For that you need to look at handledEventsToo.
Unfortunately I don't think it can be set in xaml. only code.
I seemed to have fixed the problem by setting a trigger in the control template, which binds to the RadioButton's IsMouseOver, and sets a custom DependencyProperty on the UserControl.
Something like:
<ControlTemplate TargetType="{x:Type RadioButton}">
<WPFTest:TestUC x:Name="UC" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ShowCancel" Value="True" TargetName="UC"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
I'm still confused as to why the Mouse Capture falsifies IsMouseOver on the UserControl child of the RadioButton however. Can anyone shed some light on this?
Very interesting problem. I myself would like to know more of why the UserControl IsMouseOver changes to false when the TextBlock(s) in its visuals are mouse downed upon.
However, here is another way to solve it ... maybe you will like this approach better.
Instead of using RadioButton (since you are retemplating it) why don't you just use Control? (I think IsMouseOver is getting changed to false due to the fact that it is a Button derived control.)
Following is the xaml for the Window ...
<Window
x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="Window1"
Width="300"
Height="300"
>
<Window.Resources>
<Style TargetType="{x:Type Control}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Control}">
<local:UserControl1/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border BorderBrush="Black" BorderThickness="2">
<StackPanel>
<Control x:Name="OptionButton" Height="100"/>
<TextBlock Text="{Binding ElementName=OptionButton, Path=IsMouseOver}"/>
</StackPanel>
</Border>
</Window>
EDIT:
I just wanted to add ... that if you're okay with the above approach ... then, the right thing to do is probably to just use the UserControl in the Window's visual tree versus retemplating a Control. So ... like this:
<Window
x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="Window1"
Width="300"
Height="300"
>
<Border BorderBrush="Black" BorderThickness="2">
<StackPanel>
<local:UserControl1 x:Name="OptionButton" Height="100"/>
<TextBlock Text="{Binding ElementName=OptionButton, Path=IsMouseOver}"/>
</StackPanel>
</Border>
</Window>

Resources