Hi I was wondering is there a way to only edit the Dock Ability Arrows on the Dock Guide for a docking manager using syncfusion for wpf? I can edit the complete style of the docking manager but I only want the ability to edit the arrows as I have the theme in a specific way but need the arrows only to be different is this possible at all? And if so how can I access it?
To do this you need to edit the Drag Provider Templates below is some XAML example for anyone who has a similar problem or was curious as to how to do it
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Syncfusion="http://schemas.syncfusion.com/wpf"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<!-- Control template for TopDragProvider -->
<ControlTemplate x:Key="TopDragProviderTemplate" TargetType="{x:Type ContentControl}">
<Image Name="Img" Width="29" Height="32" Syncfusion:DockPreviewManagerVS2005.ProviderAction="GlobalTop" Source="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalTop.png" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSideButtonActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Syncfusion:DockPreviewMainButtonVS2005}}}" Value="true">
<Setter TargetName="Img" Property="Source" Value="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalTopOver.png"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Control template for LeftDragProvider -->
<ControlTemplate x:Key="LeftDragProviderTemplate" TargetType="{x:Type ContentControl}">
<Image Name="Img" Width="32" Height="29" Syncfusion:DockPreviewManagerVS2005.ProviderAction="GlobalLeft" Source="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalLeft.png" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSideButtonActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Syncfusion:DockPreviewMainButtonVS2005}}}" Value="true">
<Setter TargetName="Img" Property="Source" Value="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalLeftOver.png"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Control template for RightDragProvider -->
<ControlTemplate x:Key="RightDragProviderTemplate" TargetType="{x:Type ContentControl}">
<Image Name="Img" Width="32" Height="29" Syncfusion:DockPreviewManagerVS2005.ProviderAction="GlobalRight" Source="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalRight.png" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSideButtonActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Syncfusion:DockPreviewMainButtonVS2005}}}" Value="true">
<Setter TargetName="Img" Property="Source" Value="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalRightOver.png"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Control template for BottomDragProvider -->
<ControlTemplate x:Key="BottomDragProviderTemplate" TargetType="{x:Type ContentControl}">
<Image Name="Img" Width="29" Height="32" Syncfusion:DockPreviewManagerVS2005.ProviderAction="GlobalBottom" Source="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalBottom.png" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSideButtonActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Syncfusion:DockPreviewMainButtonVS2005}}}" Value="true">
<Setter TargetName="Img" Property="Source" Value="pack://application:,,,/Syncfusion.Tools.WPF;component/Framework/DockingManager/Resources/DockPreviewVS2005GlobalBottomOver.png"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Related
I'm working on a WPF application. I have a button, which contains a Grid with a TextBlock and a Path element, as following:
<Button x:Name="btn" Margin="1">
<Button.Content>
<Grid Style="{DynamicResource button_special_hover}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="15*" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="tx" TextWrapping="Wrap" Text="{DynamicResource MenuString}" Grid.Column="2" />
<Path x:Name="path" Stretch="Fill" Fill="{DynamicResource MarkerBrush}" Data="M 65.3334,41.3334C 65.3334,45.0133 62.3467,48 58.6667" Grid.Column="0" />
</Grid>
</Button.Content>
What I want to achieve is that once I hover the grid inside the button with my mouse, I want the foreground of the text inside the textblock to turn into white and the fill color for the path element to turn into white too.
What I've tried to do is declare a style for the grid as following: (button_special_hover)
<Style x:Key="button_special_hover" TargetType="{x:Type Grid}">
<Setter Property="Background" Value="Transparent"/>
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},
Path=IsMouseOver}" Value="True">
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Path}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},
Path=IsMouseOver}" Value="True">
<Setter Property="Fill" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
I don't get what I want. Once I hover over the grid, nothing happens. Only when I hover the Textblock inside the grid, the text turns into White. Once I hover the Path, nothing happens.
How can I achieve that once I hover the grid both the textblock foreground and the Path Fill turn into White? Thanks!
Your problem is that you specified the fill on the path element.
NOTE: I 'fixed' the Data by added ",41.3334" to it.
<Path x:Name="path" Stretch="Fill" Fill="{DynamicResource MarkerBrush}" Data="M 65.3334,41.3334C 65.3334,45.0133 62.3467,48 58.6667,41.3334" Grid.Column="0" />
When you do that, you can't override it. If you specified it in the style instead then you'd get the results you want.
Remove Fill from Path:
<Path x:Name="path" Stretch="Fill" Data="M 65.3334,41.3334C 65.3334,45.0133 62.3467,48 58.6667,41.3334" Grid.Column="0" />
and add Fill to the style:
<Style x:Key="button_special_hover" TargetType="{x:Type Grid}">
<Setter Property="Background" Value="Transparent"/>
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},
Path=IsMouseOver}" Value="True">
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Path}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},
Path=IsMouseOver}" Value="True">
<Setter Property="Fill" Value="White"/>
</DataTrigger>
</Style.Triggers>
<!-- "All I did was add this line below" -->
<Setter Property="Fill" Value="{DynamicResource MarkerBrush}"/>
</Style>
</Style.Resources>
</Style>
I am new to XAML and WPF.
On Button press I want to change the canvas drawn on the button from ic_maximize to ic_restore and switch the canvas when the button is pressed again. I am using the mahapps library. Can you please tell me how to go about doing this?
I have tried a lot of different StackOverflow links, but none of them are pertinent to my problem.
Here is the style for my maximize button. I have the "IsPressed" triggers ready but not able to figure out what need to be set when it is triggered.-
<Canvas x:Key="ic_maximize" Width="13.3333" Height="13.3333" Canvas.Left="0" Canvas.Top="0">
<Rectangle Width="11.7333" Height="11.7333" Canvas.Left="2.136" Canvas.Top="-0.536002" Stretch="Fill" StrokeThickness="1.06667" StrokeLineJoin="Round" Stroke="#FF999999"/>
<Rectangle Width="11.7333" Height="11.7333" Canvas.Left="5.36442e-007" Canvas.Top="1.6" Stretch="Fill" StrokeThickness="1.06667" StrokeLineJoin="Round" Stroke="#FF999999" Fill="#FF161616"/>
</Canvas>
<Canvas x:Key="ic_restore" Width="12" Height="12" Canvas.Left="0" Canvas.Top="0">
<Rectangle Width="11.7333" Height="11.7333" Canvas.Left="5.36442e-007" Canvas.Top="0.266666" Stretch="Fill" StrokeThickness="1.06667" StrokeLineJoin="Round" Stroke="#FF999999"/>
</Canvas>
<Style x:Key="ExtendedMaxButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource MetroWindowButtonStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Name="grid" Background="{StaticResource MaxButton.Grid.background}">
<!-- either one of the ic_maximize/ic_restore canvases should come here -->
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="grid" Property="Background" Value="{StaticResource MaxButton.MouseOver.Background}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<!-- What should I write here?-->
</Trigger>
<Trigger Property="IsPressed" Value="False">
<!-- What should I write here?-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Place both Canvas on top of each other, and hide one upon IsPressed.
<Grid Name="grid">
<Canvas Background="Purple">
<Canvas.Style>
<Style TargetType="Canvas">
<Style.Triggers>
<DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Canvas.Style>
<TextBlock Text="ic_max" FontSize="48"/>
</Canvas>
<Canvas Background="Green">
<Canvas.Style>
<Style TargetType="Canvas">
<Style.Triggers>
<DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Canvas.Style>
<TextBlock Text="ic_restore" FontSize="48"/>
</Canvas>
</Grid>
I have a datagrid which contains a template column which holds a few buttons.
I need the color of these buttons to change from black to white when the row is selected.
Although I am not sure how can I reach "DataGridRow.IsSelected" from the buttons setters.
Here is what I tried and didn't work:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}"
Command="{Binding ViewModel.OnRemoveDirectoryClick, ElementName=Root}">
<Button.Style>
<Style>
<Setter Property="Button.Background">
<Setter.Value>
<ImageBrush ImageSource="../../Images/menu_delete.png"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="DataGridRow.IsSelected" Value="True">
<Setter Property="Button.Background">
<Setter.Value>
<ImageBrush ImageSource="../../Images/menu_delete_white.png"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Thanks ahead,
Yotam
Eventually I found that I needed to use DatatTrigger with a relative source to DataGridRow
<Button.Style>
<Style>
<Setter Property="Button.Background">
<Setter.Value>
<ImageBrush ImageSource="../../Images/menu_delete.png"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Button.Background">
<Setter.Value>
<ImageBrush ImageSource="../../Images/menu_delete_white.png"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
An additional and perhaps more elegant way I found to tackle this problem was using a template which contains rectangle with white filling which takes the button's background as the opacity mask.
<ControlTemplate x:Key="DataGridButtonTemplate" TargetType="{x:Type Button}">
<Grid Style="{x:Null}">
<Rectangle x:Name="Mask" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Opacity="{StaticResource NormalOpacity}" Style="{x:Null}"
OpacityMask="{TemplateBinding Background}" Fill="White" Visibility="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Converter={StaticResource BoolToVisibilityConverter}}"/>
</Grid>
</ControlTemplate>
Try putting this style as Resource
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected"
Value="True">
<Setter Property="Foreground" TargetName="YourButtonName"
Value="YourColor" />
</Trigger>
</Style.Triggers>
</Style>
I have a style defined in my resource dictionary so the style can be used in all over my application.
<Style x:Key="HyperlinkStyle" TargetType="{x:Type Hyperlink}">
<Setter Property="Foreground" Value="{StaticResource Color3}" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="TextBlock.TextDecorations" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource Color3Pressed}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource Color2NotEnabled}" />
</Trigger>
</Style.Triggers>
</Style>
I use the style in Datagrid like this :
<DataGridTemplateColumn Width="140*" CanUserReorder="False" CanUserResize="True" Header="">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate />
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell" BasedOn="{StaticResource DatagridCellHyperlinkStyle}">
<Setter Property="IsEnabled" Value="{Binding Path=MyObject, Converter={StaticResource ConverterMyObject}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Padding="{TemplateBinding Padding}" VerticalAlignment="Center">
<TextBlock Width="Auto" Height="Auto" TextTrimming="CharacterEllipsis">
<Hyperlink IsEnabled="{TemplateBinding IsEnabled}">
<InlineUIContainer TextDecorations="{Binding Path=TextDecorations, RelativeSource={RelativeSource AncestorType=TextBlock}}" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType=TextBlock}}">
<ContentPresenter Width="Auto" Height="Auto" Content="{Binding DataContext.MyObject.Name, RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
</InlineUIContainer>
<Hyperlink.Style>
<Style TargetType="Hyperlink" BasedOn="{StaticResource HyperlinkStyle}">
<EventSetter Event="Hyperlink.Click" Handler="Clic" />
</Style>
</Hyperlink.Style>
</Hyperlink>
</TextBlock>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn>
This works great but I would like to be able to have 2 colors in my style depending on a parameter.
For example, my datagrid has 1500 rows, I want to highlight 100 rows from the collection by changing their hyperlink color.
So I thought the best was to set the Tag property of the hyperlink to a custom value and use it in the style. Following this answer : https://social.msdn.microsoft.com/Forums/vstudio/en-US/d3424267-ed1f-4b30-90a1-5cca9843bd22/problem-making-a-trigger-on-the-tag-property?forum=wpf, I made the changes below :
xmlns:sys="clr-namespace:System;assembly=mscorlib"
First I've set the tag manually for each row to see if the style changes :
<Hyperlink IsEnabled="{TemplateBinding IsEnabled}" Tag="10">
and added this trigger to my hyperlink's style:
<Trigger Property="Tag">
<Trigger.Value>
<sys:Byte>10</sys:Byte> <!-- My highlighted object -->
</Trigger.Value>
<Setter Property="Foreground" Value="{StaticResource Color1}" />
</Trigger>
But it doesn't work when I launch my application (I still have "Color3" whereas I want "Color1" when Tag is equals to 10.
I've checked the output there isn't any error.
I've tried to change "sys:Byte" by "sys:String" but the result was the same.
Do I need to change my approach for this problem ? I've read maybe we can't add trigger on Tag Property.
Thank you
I suggest if you set the tag like this
<Hyperlink IsEnabled="{TemplateBinding IsEnabled}" Tag="10">
Then write the trigger in the same way:
<Trigger Property="Tag" Value="10">
...setter
</Trigger>
Or if in hyperlink you use Byte type as Tag:
<Hyperlink IsEnabled="{TemplateBinding IsEnabled}">
<Hyperlink.Tag>
<sys:Byte>10</sys:Byte>
</Hyperlink.Tag>
</Hyperlink>
Then same goes in the trigger:
<Trigger Property="Tag">
<Trigger.Value>
<sys:Byte>10</sys:Byte>
</Trigger.Value>
...setter
</Trigger>
Im coming from a C# winforms background and I would normally do all this in code.
I have several Labels that I'm using as a menu.
When the mouse hovers over them the text changes color by:
<Page.Resources>
<SolidColorBrush x:Key="normalColor" Color="White" />
<SolidColorBrush x:Key="mouseOverColor" Color="Gold" />
<Style TargetType="Label" x:Key="menuItemStyle">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Foreground" Value="{StaticResource normalColor}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource mouseOverColor}"/>
</Trigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Label x:Name="Label_Video1" Style="{StaticResource menuItemStyle}" Content="1.Video 1." FontSize="16" HorizontalAlignment="Left" Margin="25,74,0,0" VerticalAlignment="Top" MouseLeftButtonDown="Label_Video1_MouseLeftButtonDown" />
<Label x:Name="Label_Video2" Style="{StaticResource menuItemStyle}" Content="2. Video 2." FontSize="16" HorizontalAlignment="Left" Margin="25,105,0,0" VerticalAlignment="Top" MouseDown="Label_Video2_MouseDown"/>
When the user clicks a label I want it to stay a certin color (In this case Gold) and all the others to stay their normal colour. So if a label has been previously clicked and I click another label it will go from gold to white etc
When using WPF, you have to think slightly differently. We know that the Label control doesn't know when it has been clicked and it especially doesn't know when another Label element has been clicked... but some controls do. Thinking about it... a RadioButton has exactly this behaviour. Now this is where WPF really shines.
We can use RadioButtons and by providing them with a new ControlTemplate, we can make them look like plain text:
<Grid Background="Black">
<Grid.Resources>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<TextBlock Text="{TemplateBinding Content}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType={
x:Type RadioButton}}}" Value="True">
<Setter Property="Foreground" Value="Gold" />
</DataTrigger>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource
AncestorType={x:Type RadioButton}}}" Value="True">
<Setter Property="Foreground" Value="Gold" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<StackPanel Margin="5" Background="{x:Null}">
<RadioButton Content="1.Video 1." />
<RadioButton Content="2.Video 2." />
<RadioButton Content="3.Video 3." />
</StackPanel>
</Grid>
If you don't want the RadioButtons to be all together in a StackPanel, then you can use give them the same GroupName property value to ensure that they still operate as one group.