In my custom control I have ControlTemplate propety
public ControlTemplate ControlTemplate
It can be something like this:
<map:IdattMapLayer.ControlTemplate>
<ControlTemplate>
<Canvas
DataContext="{Binding
Converter={StaticResource ObjectToTrackedAssetConverter}}">
<Button
Style="{StaticResource LooklessButtonStyle}"
Width="{Binding PushpinWidth}" Height="{Binding PushpinWidth}"
Margin="{Binding PushpinMargin}"
Command="{Binding
Path=DataContext.SelectedPushpinChangedCommand,
ElementName=LayoutRoot}"
CommandParameter="{Binding}"
Cursor="Hand">
<Ellipse
Width="{Binding PushpinWidth}"
Height="{Binding PushpinWidth}"
Stroke="Black"
Fill="{Binding IsGPSDataRecent,
Converter={StaticResource BoolToGreenRedBrushConverter}}"
StrokeThickness="1">
</Ellipse>
</Button>
</Canvas>
</ControlTemplate>
</map:IdattMapLayer.ControlTemplate>
I would like to set Canvas's data context myself rather than doing it in XAML.
So, If I have ControlTemplate - how do I find first child (Canvas in this case) programmatically?
1) set x:Name attribute for Canvas.
2) override OnApplyTemplate.
3) use (Canvas)GetTemplateChild("CanvasName") for get Canvas.
ofcourse this class should inherit from Control.
Related
I ran into an interesting thing and I can't figure out how to fix it at the moment, maybe I'm missing something really simple.
I'm re-designing some of the UI but I'm not really experienced with it right now.
So I have 3 buttons and I wanted to draw patterns as the content of the buttons instead of using images.
I have managed to do so(still needs tweaking), but the buttons on hover event only triggers once my pointer enters the pattern area instead of the area of the button. Does anyone mind taking a look at it please?
<Button Grid.Column="0" Width="35" Height="35"
Command="{StaticResource MinimizeCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
Background="{x:Null}" BorderBrush="{x:Null}">
<Path Data="M20,14H4V10H20" VerticalAlignment="Center"
HorizontalAlignment="Center" Height="2.6"
Margin="7,20,7,10" Stretch="Fill" Width="16">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource MainForeColor}"/>
</Path.Fill>
</Path>
</Button>
Code : https://hastebin.com/kofaqehoti.xml
By setting the background and the border brushes of the buttons to null the button will only be clickable and detectable for hover where the paths are drawn. Replace the nulls with Transparent or #00000000 and the buttons will be invisible but clickable/hoverable (If that's a word)
<Button Grid.Column="0" Width="35" Height="35"
Command="{StaticResource MinimizeCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
Background="Transparent" BorderBrush="#00000000">
<Path Data="M20,14H4V10H20" VerticalAlignment="Center" HorizontalAlignment="Center" Height="2.6" Margin="7,20,7,10" Stretch="Fill" Width="16">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource MainForeColor}"/>
</Path.Fill>
</Path>
</Button>
I need to be able to set a Z-Index of a ContentControl, the parent, based on a child control that's inside the ContentControl.
Here's my tiny example:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Rectangle Fill="Green" Width="100" Height="100" Panel.ZIndex="5"/>
<ContentControl>
<Rectangle Fill="Red" Width="100" Height="100" Panel.ZIndex="10" />
</ContentControl>
</Grid>
</Page>
In this example, the Panel.ZIndex declared in the Red Rectangle has no effect.
I thought of two options:
Have the parent bind to the Panel.ZIndex value of the child
Have the child set the Panel.ZIndex on its parent
I couldn't figure out how to do either of these two options.
Eventually my child controls are defined in a DataTemplate which gets applied using a ContentControl, meaning I can't directly set the Panel.ZIndex property of the ContentControl
Try this:
<Grid>
<Rectangle Fill="Green" Width="100" Height="100" Panel.ZIndex="5"/>
<ContentControl Panel.ZIndex="{Binding Content.(Panel.ZIndex), RelativeSource={RelativeSource Self}}">
<Rectangle Fill="Red" Width="100" Height="100" Panel.ZIndex="10" />
</ContentControl>
</Grid>
i do have a problem with binding the visibility of my usercontrol.
The binding to a Dependency Property of type Visibility works fine and the correct value (in this case Collapsed) is held by the DP. The content of my Grid within the UserControl is set to collapsed, but the hole control doesnt collapse. It still keeps the space occupied defined by with and heigth, as referenced in the xaml.
EDIT: i found out, that the problem is that i set width and height in the xaml where i reference my usercontrol. if i don't do this, the control collapses correct (therefore binding works fine). But i need to set width and heigth in case the usercontrol is visible.
Any idea how i can solve this problem?
<my:MenuButtonBase x:Class="bxSuite.Controls.MenuButtonLarge"
xmlns:my="clr-namespace:bxSuite.Controls"
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"
Background="Black"
>
<Grid Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ButtonVisibility}" >
<StackPanel>
<Image Source="{Binding ButtonImageSource}" Margin="5,10,5,5" Width="48" Height="48" VerticalAlignment="Top" HorizontalAlignment="Center" />
<TextBlock Text="{Binding FunctionHeader}" Foreground="White" TextWrapping="Wrap" TextAlignment="Center" Padding="5,5,5,5" FontSize="12" />
</StackPanel>
</Grid>
</my:MenuButtonBase>
In XAML i reference my usercontrol like this (where the Converter produces the visibility-state correctly):
<my:MenuButtonLarge Name="btnInEuqipment" ButtonVisibility="{Binding Path=User, Converter={StaticResource ConverterUserRightVisibility}, ConverterParameter=5}" VerticalAlignment="Top" FunctionHeader="{lex:Loc Key=MenuButton_InEquipment}" Width="130" ButtonImageSource="/bxSuite.RolloutManager;component/Images/inequipment_48x48.png" BackgroundEnabled="#FF0694FD" BackgroundHover="#FF0072C6" MenuButtonClick="btnInEuqipment_MenuButtonClick" Height="95" Margin="5,10,0,0" />
Try set the visibility of the user control instead of the grid, should work.
Your code should be like this.
<my:MenuButtonBase x:Class="bxSuite.Controls.MenuButtonLarge"
xmlns:my="clr-namespace:bxSuite.Controls"
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"
Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ButtonVisibility}"
Background="Black">
<Grid>
<StackPanel>
<Image Source="{Binding ButtonImageSource}"
Margin="5,10,5,5"
Width="48"
Height="48"
VerticalAlignment="Top"
HorizontalAlignment="Center" />
<TextBlock Text="{Binding FunctionHeader}"
Foreground="White"
TextWrapping="Wrap"
TextAlignment="Center"
Padding="5,5,5,5"
FontSize="12" />
</StackPanel>
</Grid>
Dont forget to update the RelativeSource of your bind.
I have a basic WPF windows with the markup as specific below:
<Window x:Class="Application.SomeWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SomeWindow"
Topmost="True" WindowStyle="None" Height="39" Width="400"
ResizeMode="NoResize" ShowInTaskbar="False"
WindowStartupLocation="Manual" Background="Transparent"
Closing="Window_Closing" AllowsTransparency="True" Opacity="0">
<Border Background="CornflowerBlue" BorderBrush="Black" BorderThickness="0,0,0,0" CornerRadius="5,5,5,5" Opacity="0.75">
<Grid>
<!-- Display bar -->
<Image Grid.Row="1" Height="24" Margin="7,7,0,0" Name="img1" Stretch="Fill" VerticalAlignment="Top" Source="/Application;component/Images/dashboard/1.png" HorizontalAlignment="Left" Width="13" />
<Image Height="24" Margin="19,7,47,0" Name="image21" Source="/Application;component/Images/dashboard/2.png" Stretch="Fill" VerticalAlignment="Top" Grid.Row="1" Grid.ColumnSpan="2" />
<!-- Button 1 -->
<Button Style="{DynamicResource NoChromeButton}" Height="27" Margin="0,5,25,0" Name="btn1" Click="btn1_Click" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Width="23" ToolTip="1">
<Image Height="26" HorizontalAlignment="Right" Name="img1" Source="/Application;component/Images/dashboard/3.png" VerticalAlignment="Top" Width="22" Stretch="Fill" />
</Button>
<!-- Button 2 -->
<Button Style="{DynamicResource NoChromeButton}" Height="27" Margin="0,5,5,0" Name="btn2" Click="btn2_Click" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Width="23" ToolTip="2">
<Image Height="26" HorizontalAlignment="Right" Name="img2" Source="/Application;component/Images/dashboard/4.png" VerticalAlignment="Top" Width="22" Stretch="Fill" />
</Button>
</Grid>
</Border>
</Window>
Here is what it looks like now:
What I'd really like to do is make it so that initially looks like this:
Then, once mouseover happens, to fade background opacity in from 0 so it looks like the first image. The problem is that if I set the Border or Grid Background color to Transparent with the goal of fading in on mouseover, then everything inside the Border or Grid is affected as well.
Is there a way to manage the opacities of window and its UI elements seperately? Or perhaps there is a totally different route to take to get this background fade on mouseover? Thanks.
There are two options. Number one is to just move the outer border inside the grid, as the first child (and have the other controls alongside it, not in it). That way it will fade by itself, but still be behind the other controls. You will of course either have to set ColumnSpan/RowSpan, or wrap the entire thing in another Grid.
The second option is to just fade the background, not the entire border:
<Border ...>
<Border.Background>
<SolidColorBrush Color="CornflowerBlue" Opacity="0.5"/>
</Border.Background>
...
try this trick - draw a rectangle or border with dimensions bind to parent or ElementName.
It won't affect rest of elements of tree. Works for me.
<Grid x:Name="abc">
<Border
Width="{Binding ActualWidth, ElementName=abc}"
Height="{Binding ActualHeight, ElementName=abc}"
Background="Blue"
Opacity="0.5"/>
//buttons or inner grid
...
</Grid>
If you don'w want to use ElementName, simply replace Width and Height by
Width="{Binding ActualWidth, Source={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
Height="{Binding ActualHeight, Source={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
i have the following DataTemplate which is defined in a Resources.xaml which holds my Visual Templates for my programs (thats why no Eventhandlers are included here)
<DataTemplate x:Key="PointTemplate">
<Ellipse x:Name="Ellipse" Width="8" Height="8" Stroke="Black" StrokeThickness="1.5" Fill="White" Visibility="{Binding DataItem.Visibility}"/>
</DataTemplate>
then its used for a visual in Code by loading it from my Resources:
...
line.PointTemplate = (DataTemplate) Application.Current.Resources["PointTemplate"];
Now i want to add an EventHandler and Cursor to the Ellipse inside the PointTemplate (=DataTemplate).
but.. how do i do this?
thanks in advance!
One of the ways to handle the event is to use a Button with a command:
<DataTemplate x:Key="PointTemplate">
<Button Command="Zoom">
<Button.Template>
<ControlTemplate>
<Ellipse x:Name="Ellipse" Width="80" Height="80" Stroke="Black" StrokeThickness="1.5" Fill="White"/>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
And you can add a handler for the command accordingly.