I bound ViewScale to Grid's ScaleTransform and when the app starts it correctly scales by 2. But when I change ViewScale by pressing F12, it doesn't trigger ScaleTransform update even though the property value is changed.
Here is the code:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace test
{
public partial class MainWindow : Window
{
public event PropertyChangedEventHandler PropertyChanged;
protected void SetField<T> ( ref T field, T value, string propertyName )
{
if ( !EqualityComparer<T>.Default.Equals ( field, value ) )
{
field = value;
PropertyChanged?.Invoke ( this, new PropertyChangedEventArgs ( propertyName ) );
}
}
decimal viewScale = 2;
public decimal ViewScale
{
get => this.viewScale;
set => SetField ( ref this.viewScale, value,
"ViewScale"
);
}
ObservableCollection<Coin> _coins;
public ObservableCollection<Coin> Coins { get => _coins; set => SetField ( ref _coins, value, nameof ( _coins ) ); }
public ICollectionView CollectionView;
public MainWindow ( )
{
this.Coins = new ObservableCollection<Coin> ( );
for ( int i = 0 ; i < 100 ; ++i )
this.Coins.Add ( new Coin ( "Coin 1", i ) );
this.DataContext = this;
InitializeComponent ( );
this.PreviewKeyDown += MainWindow_PreviewKeyDown;
}
void MainWindow_PreviewKeyDown ( object sender, KeyEventArgs e )
{
Console.WriteLine ( e.Key );
if ( e.Key == Key.Home )
{
this.dataGrid.ScrollIntoView ( this.dataGrid.Items [ this.dataGrid.Items.Count - 1 ] );
this.dataGrid.UpdateLayout ( );
this.dataGrid.ScrollIntoView ( this.dataGrid.Items [ 0 ] );
}
else if ( e.Key == Key.F12 )
{
this.ViewScale += 0.1m;
}
}
void MainWindow_KeyDown ( object sender, KeyEventArgs e )
{
}
}
public class Coin
{
public string Symbol { get; set; }
public int PNL { get; set; }
public SolidColorBrush Color2 { get; set; }
public Coin ( string symbol, int pnl )
{
this.Symbol = symbol;
this.PNL = pnl;
Random rnd = new Random ( );
Color c = Color.FromRgb ( ( byte ) rnd.Next ( 256 ), ( byte ) rnd.Next ( 256 ), ( byte ) rnd.Next ( 256 ) );
this.Color2 = new SolidColorBrush ( c );
}
}
}
XAML:
<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"
Name="myMainWindow"
SizeToContent="Width"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Profit Tracker"
WindowStyle="None"
Topmost="True"
Height="426">
<Window.Resources>
<Style x:Key="DataGridColumnSeparatorStyle" TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="#1e90ff"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DataGridColumnAlarmStyle" TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Fill="#000000"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="#FFF" />
<Setter Property="AlternationCount" Value="2" />
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="RowStyleWithAlternation" TargetType="DataGridRow">
<Setter Property="Background" Value="#141414"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="AlternationIndex" Value="0">
<Setter Property="Background" Value="#141414"/>
</Trigger>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Background" Value="#282828"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="-1,0,0,0" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<!--<Setter Property="BorderBrush" Value="#2eff00" />
<Setter Property="BorderThickness" Value="1" />-->
<Setter Property="Background" Value="Orange"/>
<!--<Setter Property="Margin" Value="-1,0,0,0" />-->
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell">
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Stretch"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#1e90ff" />
<Setter Property="BorderThickness" Value="1" />
<!--<Setter Property="Background" Value="Red"/>-->
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Column.DisplayIndex, RelativeSource={RelativeSource Self}}" Value="4"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderThickness="1" Background="#006400" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left" Fill="#75001D" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<CollectionViewSource Source="{Binding Coins}" IsLiveSortingRequested="True" x:Key="MyKey" />
</Window.Resources>
<Grid>
<Grid.LayoutTransform>
<ScaleTransform ScaleX="{Binding ViewScale, ElementName=myMainWindow}" ScaleY="{Binding ViewScale, ElementName=myMainWindow}" />
</Grid.LayoutTransform>
<DataGrid Name="dataGrid" ItemsSource="{Binding Source={StaticResource MyKey}}" SelectionMode="Single" GridLinesVisibility="None" HorizontalScrollBarVisibility="Hidden" RowHeaderWidth="0" IsReadOnly="True" CanUserAddRows="False" CanUserResizeColumns="False" CanUserResizeRows="False" AutoGenerateColumns="False" RowStyle="{StaticResource RowStyleWithAlternation}">
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="0" Width="2" CellStyle="{StaticResource DataGridColumnSeparatorStyle}"/>
<DataGridTextColumn Header="PNL" Width="60" SortMemberPath="Balance.UnitPrice" Binding="{Binding Path=PNL}" />
<DataGridTemplateColumn MinWidth="0" Width="2" CellStyle="{StaticResource DataGridColumnSeparatorStyle}" CanUserSort="False"/>
<DataGridTemplateColumn Header="Price" Width="60" SortMemberPath="Price">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid>
<Border BorderBrush="#241C59" BorderThickness="1" CornerRadius="1" Background="#2D255B">
<Border BorderBrush="#206fb6" BorderThickness="4" CornerRadius="2" ClipToBounds="True" Margin="-1" HorizontalAlignment="Stretch">
<Border.Effect>
<BlurEffect Radius="10"/>
</Border.Effect>
</Border>
</Border>
<Border Margin="1" VerticalAlignment="Stretch" BorderThickness="0." Background="#69ABDB" HorizontalAlignment="Left" Width="30">
<Border BorderBrush="#38e2ff" BorderThickness="2" CornerRadius="2" ClipToBounds="False">
<Border.Effect>
<BlurEffect Radius="5"/>
</Border.Effect>
</Border>
</Border>
</Grid>
<TextBlock Text="25%" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Vol BTC/h" Width="30" SortMemberPath="LastHourVolumeInBtc">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="ABCDE" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Vol BTC/h" Width="40">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ProgressBar Value="0.3" Minimum="0" Maximum="1"/>
<TextBlock Text="12345" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Net BTC/m" Width="60"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
In order to provide property changed notifications, you have to implement the INotifyPropertyChanged interface in the type that the bound property is defined. You missed this part in your MainWindow code-behind, which is also the data context of your window.
public partial class MainWindow : Window, INotifyPropertyChanged
Although you defined the PropertyChanged event and your SetField method raises the event correctly, WPF will not be aware of it, if you do not declare the interface on your class definition.
I want to change the icon on my button. Here is the xaml of my button:
<Button Name="InitPurgeBtn" Click="InitPurgeClick">
<Rectangle Width="35" Height="45" Margin="0,0,0,0">
<Rectangle.Fill>
<VisualBrush Stretch="Fill" Visual="{StaticResource InitIcon}" />
</Rectangle.Fill>
</Rectangle>
</Button>
The probleme is I don't know how to acces the Visual property of the Rectangle of my button in my controller to change "InitIcon" by "PurgeIcon"
All my icon are implement in xaml:
<Viewbox x:Key="ExtinctionIcon" Stretch="Uniform" x:Shared="False">
<Canvas Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="40" Height="40" Stretch="Fill" Fill="{Binding Foreground,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"
Data="M15,24H17V22H15M16.56,{...}24H13V22H11M7,24H9V22H7V24Z"/>
</Canvas>
</Viewbox>
Edit :
I change my button and he is like this now :
<Button Name="InitBtn" Style="{StaticResource RoundButton}" Width="70" Height="70"
Click="InitPurgeClick" Content="{StaticResource InitIcon}">
</Button>
I want to change the icon in my code so I try to set Content property like this :
InitBtn.Content = "{StaticResource ExtinctionIcon}";
But this way just replace my icon with the string "StaticResource.."
Updated to reflect new information
You updated your question with some new information that changes things a lot.
Since you are trying to update Button.Content in code, you won't be able to use the MarkupExtension. MarkupExtensions (the stuff inside { } in the XAML) are only evaluated when the view is initially created. After that, they behave just like regular strings, so trying to set one in code won't work.
To set the value in code, you will need to manually do what the MarkupExtension is doing; find the resource by name, and set the value directly. You can do this with the following code (assuming a reference to InitPurgeBtn).
InitPurgeBtn.Content = InitPurgeBtn.FindResource("ExtinctionIcon");
Previous Answer
You should be able to add your icon to the Content of the Button directly, as it seems to be defined as a resource somewhere (because of the x:Key attribute). Your code doesn't show where exactly that is though, so I can't grantee this will work without some modification.
<Button Name="InitPurgeBtn"
Width="100"
Height="40"
Content="{StaticResource ExtinctionIcon}" />
In order for that to work the ExtinctionIcon resource will have to be defined someplace accessible to the button, meaning either in an ancestor of the button, or in App.xaml.
The fact that the resource is defined with x:Shared="false" seems to indicate that it was designed to be used in exactly this way, as that is required for visual elements that can possibly be hosted in multiple places simultaneously.
Alternatively, you could just copy and embed the icon directly in to the button.
<Button Name="InitPurgeBtn"
Click="InitPurgeClick">
<Viewbox Stretch="Uniform">
<Canvas Width="76"
Height="76"
Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="40"
Height="40"
Stretch="Fill"
Fill="{Binding Foreground,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType=Button}}"
Data="M15,24H17V22H15M16.56,{...}24H13V22H11M7,24H9V22H7V24Z"/>
</Canvas>
</Viewbox>
</Button>
You may use Content property.
<Button Name="InitPurgeBtn" Width="100" Height="40">
<Button.Content>
<Image Source=".\Icon.PNG"/>
</Button.Content>
</Button>
If you just want a single (xaml) icon, you can bind the content property of your button to your icon resource.
The control below gives an enhanced display - a xaml icon plus a text caption, including two colours for the icon and support for disabled state.
MyXamlIconHost.cs
public enum CaptionPosition { None, ToLeftOfIcon, AboveIcon, ToRightOfIcon, BelowIcon }
public enum IconSize { Small, Medium, Large, XLarge, XxLarge }
public class myXamlIconHost : Control
{
private static readonly Brush DefaultForeground = new SolidColorBrush(Color.FromRgb(32,32,32));
private static readonly Brush DefaultHighlight = Brushes.DarkOrange;
private static readonly Brush DefaultDisabledForeground = new SolidColorBrush(Color.FromRgb(192, 192, 192));
private static readonly Brush DefaultDisabledHighlight = new SolidColorBrush(Color.FromRgb(128, 128, 128));
static myXamlIconHost()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(myXamlIconHost), new FrameworkPropertyMetadata(typeof(myXamlIconHost)));
}
public FrameworkElement XamlIcon
{
get { return (FrameworkElement)GetValue(XamlIconProperty); }
set { SetValue(XamlIconProperty, value); }
}
public static readonly DependencyProperty XamlIconProperty =
DependencyProperty.Register("XamlIcon", typeof(FrameworkElement), typeof(myXamlIconHost), new PropertyMetadata(null));
public IconSize IconSize
{
get { return (IconSize)GetValue(IconSizeProperty); }
set { SetValue(IconSizeProperty, value); }
}
public static readonly DependencyProperty IconSizeProperty =
DependencyProperty.Register("IconSize", typeof(IconSize), typeof(myXamlIconHost), new PropertyMetadata(IconSize.Medium));
public string Caption
{
get { return (string)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(string), typeof(myXamlIconHost), new PropertyMetadata(null));
public CaptionPosition CaptionPosition
{
get { return (CaptionPosition)GetValue(CaptionPositionProperty); }
set { SetValue(CaptionPositionProperty, value); }
}
public static readonly DependencyProperty CaptionPositionProperty =
DependencyProperty.Register("CaptionPosition", typeof(CaptionPosition), typeof(myXamlIconHost), new PropertyMetadata(CaptionPosition.ToRightOfIcon));
public Brush StandardForeground
{
get { return (Brush)GetValue(StandardForegroundProperty); }
set { SetValue(StandardForegroundProperty, value); }
}
public static readonly DependencyProperty StandardForegroundProperty =
DependencyProperty.Register("StandardForeground", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultForeground));
public Brush StandardHighlight
{
get { return (Brush)GetValue(StandardHighlightProperty); }
set { SetValue(StandardHighlightProperty, value); }
}
public static readonly DependencyProperty StandardHighlightProperty =
DependencyProperty.Register("StandardHighlight", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultHighlight));
public Brush DisabledForeground
{
get { return (Brush)GetValue(DisabledForegroundProperty); }
set { SetValue(DisabledForegroundProperty, value); }
}
public static readonly DependencyProperty DisabledForegroundProperty =
DependencyProperty.Register("DisabledForeground", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultDisabledForeground));
public Brush DisabledHighlight
{
get { return (Brush)GetValue(DisabledHighlightProperty); }
set { SetValue(DisabledHighlightProperty, value); }
}
public static readonly DependencyProperty DisabledHighlightProperty =
DependencyProperty.Register("DisabledHighlight", typeof(Brush), typeof(myXamlIconHost), new PropertyMetadata(DefaultDisabledHighlight));
}
// ==============================================================================================================================================
public class myXamlIconSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
const int defaultSize = 24;
if (!(value is IconSize))
return defaultSize;
var iconSizeValue = (IconSize)value;
switch (iconSizeValue)
{
case IconSize.Small:
return defaultSize * 2 / 3;
case IconSize.Large:
return defaultSize * 3 / 2;
case IconSize.XLarge:
return defaultSize * 2;
case IconSize.XxLarge:
return defaultSize * 5 / 2;
default:
return defaultSize;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
MyXamlIconHost.xaml
<Style TargetType="{x:Type ctrl:myXamlIconHost}">
<Setter Property="Focusable" Value="False" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:myXamlIconHost}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.Resources>
<ctrl:myXamlIconSizeConverter x:Key="IconSizeConverter" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="PART_CaptionTextBlock"
Grid.Row="1"
Grid.Column="0"
Margin="8,0,8,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{TemplateBinding StandardForeground}"
Text="{TemplateBinding Caption}" />
<!-- Set DataContext to "self" so that the Xaml Icon item can bind to the Foreground and BorderBrush properties -->
<ContentControl x:Name="PART_IconPresenter"
Grid.Row="1"
Grid.Column="1"
Width="{TemplateBinding IconSize,
Converter={StaticResource IconSizeConverter}}"
Height="{TemplateBinding IconSize,
Converter={StaticResource IconSizeConverter}}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderBrush="{TemplateBinding StandardHighlight}"
Content="{TemplateBinding XamlIcon}"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Focusable="False"
Foreground="{TemplateBinding StandardForeground}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_CaptionTextBlock" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisabledForeground}" />
<Setter TargetName="PART_IconPresenter" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisabledHighlight}" />
<Setter TargetName="PART_IconPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DisabledForeground}" />
</Trigger>
<Trigger Property="CaptionPosition" Value="None">
<Setter TargetName="PART_CaptionTextBlock" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="CaptionPosition" Value="ToLeftOfIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="0" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,0,8,0" />
</Trigger>
<Trigger Property="CaptionPosition" Value="ToRightOfIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="2" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,0,8,0" />
</Trigger>
<Trigger Property="CaptionPosition" Value="AboveIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="0" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,0,8,4" />
</Trigger>
<Trigger Property="CaptionPosition" Value="BelowIcon">
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Column" Value="1" />
<Setter TargetName="PART_CaptionTextBlock" Property="Grid.Row" Value="2" />
<Setter TargetName="PART_CaptionTextBlock" Property="Margin" Value="8,4,8,0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
Example Usage
<Window ... >
<Window.Resources>
<Grid x:Key="TestIcon" x:Shared="False" Background="Transparent">
<Path Stretch="Fill" Data=" M 0,0 M 100,100 M 0,0 L 0,100 L 100,100 L 100,60 L 90,60 L 90,90 L 10,90 L 10,10 L 90,10 L 90,40 L 100,40 L 100,0 z" Fill="{ Binding Foreground, FallbackValue=Cyan}"/>
<Path Stretch="Fill" Data=" M 0,0 M 100,100 M 70,45 L 100,45 L 100,55 L 70,55 z" Fill="{ Binding BorderBrush, FallbackValue=Magenta}"/>
</Grid>
</Window.Resources>
<Button HorizontalAlignment="Center" VerticalAlignment="Center">
<Border Background="LightBlue">
<ctrls:myXamlIconHost Caption="The Caption" XamlIcon="{StaticResource TestIcon}" IconSize="XxLarge" Padding="20" />
</Border>
</Button>
</Window>
I want to show my GroupName on left and button "ShowOnly" on the right of header row.
I tried with this code but doesn't works.
Could anyone help me?
Thx
My code :
<Expander IsExpanded="True" >
<Expander.Header>
<DockPanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding Path=Name}" FontSize="18"></TextBlock>
<Button Style="{StaticResource ButtonStyle}" Content="Show Only" HorizontalAlignment="Right" Padding="15,0,15,0" Click="Button_Click"></Button>
</DockPanel>
</Expander.Header>
<Expander.Style>
<Style TargetType="{x:Type Expander}">
<Setter Property="Background" Value="#f0f0f5"></Setter>
<Setter Property="TextElement.FontFamily" Value="Arial Nova"/>
</Style>
</Expander.Style>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
My ButtonStyle :
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Background" Value="#66e0ff" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="#66e0ff" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I tried also with an DockPanel, but same result.
You need to set the HorizontalAlignment property of the ContentPresenter that is defined in the Expander's default control template to Stretch.
The easiest way to do this is probably to handle the Loaded event of the Expander and use a helper method that finds the ContentPresenter in the visual tree:
private void Expander_Loaded(object sender, RoutedEventArgs e)
{
Expander expander = sender as Expander;
System.Windows.Controls.Primitives.ToggleButton HeaderSite = GetChildOfType<System.Windows.Controls.Primitives.ToggleButton>(expander);
if (HeaderSite != null)
{
ContentPresenter cp = GetChildOfType<ContentPresenter>(HeaderSite);
if (cp != null)
cp.HorizontalAlignment = HorizontalAlignment.Stretch;
}
}
private static T GetChildOfType<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
<Expander IsExpanded="True" Loaded="Expander_Loaded">
<Expander.Header>
<DockPanel HorizontalAlignment="Stretch">
<Button Style="{StaticResource ButtonStyle}" Content="Show Only" DockPanel.Dock="Right" Padding="15,0,15,0" Click="Button_Click"></Button>
<TextBlock Text="{Binding Path=Name}" FontSize="18"></TextBlock>
</DockPanel>
</Expander.Header>
<Expander.Style>
<Style TargetType="{x:Type Expander}">
<Setter Property="Background" Value="#f0f0f5"></Setter>
<Setter Property="TextElement.FontFamily" Value="Arial Nova"/>
</Style>
</Expander.Style>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
Set width of DockPanel to width of expander so that it will stretch properly.
<DockPanel HorizontalAlignment="Stretch" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}, Path=ActualWidth}">
You can refer to these solutions:
https://joshsmithonwpf.wordpress.com/2007/02/24/stretching-content-in-an-expander-header/
I’m trying to create custom Itemscontrol class to display a group of different shapes.
To speed up process, I have reused source code from CodeProject (WPF Diagram Designer - Part 4) where all implementation is done but shapes are added from XAML code. For my purposes, I need to add them from code behind (dynamically) so I bound custom Itemscontrol to list of ObservableCollection. Now, instead of shapes be presented like this:
I get something like this:
Can somebody tell me what I’m doing wrong?
Any help will be appreciated. Thanks in advance.
XAML:
<s:Toolbox x:Key="FlowChartStencils" ItemsSource="{Binding ElementName=MyDesigner, Path=ToolboxDataItems}" ItemTemplate="{StaticResource toolboxItemTemplate}" ItemSize="190,150" SnapsToDevicePixels="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
</s:Toolbox>
<DataTemplate x:Key="toolboxItemTemplate">
<Grid Margin="5,5,5,5">
<Path Style="{StaticResource Process}">
<s:DesignerItem.DragThumbTemplate>
<ControlTemplate>
<Path Style="{StaticResource Process_DragThumb}"/>
</ControlTemplate>
</s:DesignerItem.DragThumbTemplate>
</Path>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text=" {Binding Title}" IsHitTestVisible="False" FontWeight="Bold"/>
</Grid>
</DataTemplate>
<Style x:Key="Process" TargetType="Path" BasedOn="{StaticResource FlowChartItemStyle}">
<Setter Property="Data" Value="M 0,0 H 60 V40 H 0 Z"/>
</Style>
<Style x:Key="Process_DragThumb" TargetType="Path" BasedOn="{StaticResource Process}">
<Setter Property="IsHitTestVisible" Value="true"/>
<Setter Property="Fill" Value="Transparent"/>
<Setter Property="Stroke" Value="Transparent"/>
</Style>
<Style x:Key="FlowChartItemStyle" TargetType="Path">
<Setter Property="Fill" Value="{StaticResource ItemBrush}"/>
<Setter Property="Stroke" Value="{StaticResource ItemStroke}"/>
<Setter Property="StrokeThickness" Value="1"/>
<Setter Property="StrokeLineJoin" Value="Round"/>
<Setter Property="Stretch" Value="Fill"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
</Style>
<Brush x:Key="ItemStroke">#FFD69436</Brush>
<LinearGradientBrush x:Key="ItemBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FAFBE9" Offset="0" />
<GradientStop Color="Orange" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
Code behind:
// Implements ItemsControl for ToolboxItems
public class Toolbox : ItemsControl
{
// Defines the ItemHeight and ItemWidth properties of
// the WrapPanel used for this Toolbox
public Size ItemSize
{
get { return itemSize; }
set { itemSize = value; }
}
private Size itemSize = new Size(50, 50);
// Creates or identifies the element that is used to display the given item.
protected override DependencyObject GetContainerForItemOverride()
{
return new ToolboxItem();
}
// Determines if the specified item is (or is eligible to be) its own container.
protected override bool IsItemItsOwnContainerOverride(object item)
{
return (item is ToolboxItem);
}
}
// Represents a selectable item in the Toolbox/>.
public class ToolboxItem : ContentControl
{
…
}
public class ToolboxDataItem : DependencyObject
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register( "Title", typeof( string ),
typeof(ToolboxDataItem), new UIPropertyMetadata(""));
public ToolboxDataItem(string title)
{
Title = title;
}
}
public partial class DesignerCanvas : Canvas
{
private ObservableCollection<ToolboxDataItem> toolboxDataItems = new ObservableCollection<ToolboxDataItem>();
public ObservableCollection<ToolboxDataItem> ToolboxDataItems
{
get { return toolboxDataItems; }
}
public DesignerCanvas()
{
ToolboxDataItem toolboxDataItem = new ToolboxDataItem("123");
ToolboxDataItems.Add(toolboxDataItem );
toolboxDataItem = new ToolboxDataItem("456");
ToolboxDataItems.Add(toolboxDataItem );
}
}
MyDesigner:
<s:DesignerCanvas Focusable="true" x:Name="MyDesigner"
Background="{StaticResource WindowBackgroundBrush}" FocusVisualStyle="{x:Null}"
ContextMenu="{StaticResource DesignerCanvasContextMenu}"/>
So I started by trying to get an app going with the code you shared but the styles were all in an incorrect order, so after the styles were set correctly I got arround to an example like this:
<Window.Resources>
<ResourceDictionary>
<Brush x:Key="ItemStroke">#FFD69436</Brush>
<LinearGradientBrush x:Key="ItemBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FAFBE9" Offset="0" />
<GradientStop Color="Orange" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<Style x:Key="FlowChartItemStyle" TargetType="Path">
<Setter Property="Fill" Value="{StaticResource ItemBrush}"/>
<Setter Property="Stroke" Value="{StaticResource ItemStroke}"/>
<Setter Property="StrokeThickness" Value="1"/>
<Setter Property="StrokeLineJoin" Value="Round"/>
<Setter Property="Stretch" Value="Fill"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
</Style>
<Style x:Key="Process" TargetType="Path" BasedOn="{StaticResource FlowChartItemStyle}">
<Setter Property="Data" Value="M 0,0 H 60 V40 H 0 Z"/>
</Style>
<DataTemplate x:Key="toolboxItemTemplate">
<Grid Margin="5,5,5,5">
<Path Style="{StaticResource Process}">
</Path>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Title}" IsHitTestVisible="False" FontWeight="Bold"/>
</Grid>
</DataTemplate>
<Style x:Key="Process_DragThumb" TargetType="Path" BasedOn="{StaticResource Process}">
<Setter Property="IsHitTestVisible" Value="true"/>
<Setter Property="Fill" Value="Transparent"/>
<Setter Property="Stroke" Value="Transparent"/>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ItemsControl Background="Yellow"
ItemsSource="{Binding ToolboxDataItems}"
ItemTemplate="{StaticResource toolboxItemTemplate}"
SnapsToDevicePixels="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
</ItemsControl>
</Grid>
So if you check this example to yours then your problem might be in one of two places:
1) The Text binding of the TextBlock (notice the space before the {):
2) Or the Path inside the ItemsSource binding of the toolbox
<s:Toolbox x:Key="FlowChartStencils" ItemsSource="{Binding ElementName=MyDesigner, Path=ToolboxDataItems}" ItemTemplate="{StaticResource toolboxItemTemplate}" ItemSize="190,150" SnapsToDevicePixels="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
Here try something like ItemsSource="{Binding ToolboxDataItems, ElementName=MyDesigner}"