I am doing a program in WPF that has different rectangles disposed inside a grid. They all have an imagesource binding that makes the image change dynamically throughout the program. It's similar to the 2048. The thing is that now I want to make this rectangle change its imagesource when the mouse is over it. Like I already did an imagesource binding I cant figure out how to do it.
<ListBox Grid.Row="1" ItemsSource="{Binding Tiles}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="{Binding Converter={StaticResource BackgroundColor2048Converter}}" Width="106.25px" Height="106.25px" CornerRadius="3" BorderThickness="1" VerticalAlignment="Stretch" Focusable="False" HorizontalAlignment="Stretch" Margin="7">
<Rectangle Width="104.25px" Height="104.25px" MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" >
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding Converter={StaticResource ImageBackgroundColor2048Converter}, Mode=OneWay}"/>
</Rectangle.Fill>
</Rectangle>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
That's the xaml code regarding the rectangle. The imagesource converter works and is used to change the image during the game. But now I want to change that image too when the mouseenter event triggers. And thats where I am completely lost to, on how to do it.
You do this through a trigger:
<Rectangle Width="104.25px" Height="104.25px" MouseEnter="Rectangle_MouseEnter" MouseLeave="Rectangle_MouseLeave" >
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" >
<Setter.Value>
<ImageBrush ImageSource="{Binding Converter={StaticResource ImageBackgroundColor2048Converter}, Mode=OneWay}"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Rectangle.IsMouseOver" Value="True">
<Setter Property="Fill" >
<Setter.Value>
<!-- Whatever you want here -->
<ImageBrush ImageSource="{Binding MouseOverImageUri}" />
</Setter.Value>
</Setter>
</Trigger>
</Style>
</Rectangle.Style>
</Rectangle>
Note that you have to set the default value through a style. The reason for this is that triggers override styles, but directly applied attributes override triggers. In this case, you want the trigger to win.
Related
This binding is driving me crazy, tried all sort of (even supposedly identical) solutions from stackoverflow. I cannot figure out why a binding does not work...
Problem:
I have a style with a ControlTemplate that is applied to a GridViewColumnHeader. This is the style with the ControlTemplate property:
<Style x:Key="GridHeaderWithInkColor" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<Border BorderThickness="0,0,0,1" BorderBrush="White">
<StackPanel Margin="0,0,0,10" Orientation="Vertical">
<TextBlock Text="{TemplateBinding Content}" Padding="5"
Width="{TemplateBinding Width}" TextAlignment="Left"
FontSize="24" Foreground="White"/>
<Rectangle Height="15" Width="70" Margin="10" RadiusX="5" RadiusY="5" StrokeThickness="2" Stroke="DarkGray" HorizontalAlignment="Center">
<Rectangle.Fill>
<SolidColorBrush Color="???????????????"/>
</Rectangle.Fill>
</Rectangle>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I use the template as following in a GridViewHeaderColumn:
<GridViewColumn HeaderContainerStyle="{StaticResource GridHeaderWithInkColor}" local:ExtendedProps.InkColor="{Binding MachineInfo.BarColorsList[0]}"/>
local:ExtendedProps.InkColor is a property I defined myself to be able to use it in xaml.
**Question is:
How can I bind SolidColorBrush inside ControlTemplate to property local:ExtendedProps.InkColor in GridViewColumn at the time of use.**
I tried this (and other variations, templatebindings, etc.) with no luck:
<SolidColorBrush Color="{Binding DataContext.IsItemSelected,
RelativeSource={RelativeSource AncestorType=GridViewColumn}}"/>
The two things that might be doing my life difficult are (I think):
The SolidColorBrush is nested in other controls.
The property I try to use is a custom-defined property (I am sure it is correctly defined).
How can I bind SolidColorBrush inside ControlTemplate to property local:ExtendedProps.InkColor in GridViewColumn at the time of use.
The GridViewColumnHeader has a Column property that you can use to bind a property of the GridViewColumn:
Color="{Binding Path=Column.(local:ExtendedProps.InkColor),
RelativeSource={RelativeSource AncestorType=GridViewColumnHeader}}"
The column isn't a visual ancestor of the header so using {RelativeSource AncestorType=GridViewColumn} won't work.
I am wanting to just set the title bar and border of a WPF window but the title background property doesn't look to be exposed in the class.
I want to leave all default Window behavior and just set the color property of Title Bar and Border
What is the correct property to set?
I am refrencing: https://learn.microsoft.com/en-us/dotnet/api/system.windows.shell.windowchrome?view=netframework-4.7.2
<ResourceDictionary>
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome/>
</Setter.Value>
</Setter>
<Setter Property="??" Value="Blue"/>
</Style>
</ResourceDictionary>
The only property I see is the Title Property and setting its color has no effect
So I resolved this and it was more involved then I had originally thought. Since the title bar is in the non-client area when editing it I would lose the visibility of the corner buttons.
In the end I had to reconstruct the title bar and create a class to implement the buttons to get the look I desired.
This will give you a window with a border and the title bar will also have a color. You need to implement the corner buttons though.
xmlns:shell="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
<Style x:Key="StandardStyle" TargetType="{x:Type Window}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}" >
<Grid>
<!--Title Panel-->
<DockPanel LastChildFill="True">
<Border Background="Blue" DockPanel.Dock="Top"
Height="{x:Static SystemParameters.CaptionHeight}" x:Name="titlebar">
<Grid>
<!--Title text only-->
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}"
VerticalAlignment="Top" HorizontalAlignment="Center" Background="Transparent" />
<usercontrols:CornerButtons HorizontalAlignment="Right"/>
</Grid>
</Border>
<!--Provides the actual content control-->
<Border Margin="0,0,0,0" >
<AdornerDecorator>
<ContentPresenter Content="{TemplateBinding Content}"/>
</AdornerDecorator>
</Border>
</DockPanel>
<!--Provides the actual window border-->
<Border
Margin="0,0,0,0"
Background="White"
Grid.ZIndex="-1"
BorderThickness="2,2,2,2" BorderBrush="Blue"
>
</Border>
<!--This is the top left system button-->
<!--<Button
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(shell:WindowChrome.WindowChrome).ResizeBorderThickness}"
Padding="1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
shell:WindowChrome.IsHitTestVisibleInChrome="True"
Command="{x:Static shell:SystemCommands.ShowSystemMenuCommand}"
CommandParameter="{Binding ElementName=CalcWindow}">
<Image
Width="16"
Height="16"
shell:WindowChrome.IsHitTestVisibleInChrome="True"
Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon}" />
</Button>-->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I'm using the TextBox below, which in order to apply a DropShadowEffect on its text, uses a ControlTemplate. I managed to get the TextWrapping to work, but once the TextBox fills up, it's content goes out of view. How do I replicate the Auto scrolling to the bottom feature of a native TextBox?
<TextBox TextWrapping="Wrap"
Foreground="LimeGreen"
Background="Black"
Margin="10,40,10,40"
FontSize="40"
HorizontalAlignment="Stretch"
x:Name="Inp"
FontFamily="Courier New"
CaretBrush='LimeGreen'>
<TextBox.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid x:Name="RootElement">
<ScrollViewer>
<ContentPresenter Content="{TemplateBinding Text}">
<ContentPresenter.Effect>
<DropShadowEffect ShadowDepth="4"
Direction="330"
Color="LimeGreen"
Opacity="1"
BlurRadius="5" />
</ContentPresenter.Effect>
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property='TextWrapping'
Value='Wrap' />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Resources>
</TextBox>
This solution is a bit different that what you might expect. I think using the ContentPresenter is the wrong way because in the end you still want the functionality of the TextBox. So my solution focuses on getting rid of the border and focus indicator that mess up the drop shadow effect:
<TextBox x:Name="Inp"
Height="100"
HorizontalAlignment="Stretch"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
CaretBrush="LimeGreen"
FontFamily="Courier New"
FontSize="40"
Foreground="LimeGreen"
TextWrapping="Wrap">
<TextBox.Effect>
<DropShadowEffect BlurRadius="5"
Direction="330"
Opacity="1"
ShadowDepth="4"
Color="LimeGreen" />
</TextBox.Effect>
<TextBox.FocusVisualStyle>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate/>
</Setter.Value>
</Setter>
</Style>
</TextBox.FocusVisualStyle>
</TextBox>
I set the Background, BorderBrush to be transparent (=> no shadow). I removed the ContentPresenter; it's a 'regular textbox now. And to remove the focus border I set the FocusVisualStyle to an empty Template.
I have this XAML code for a button. I need this button to just be a circle of a solid color.
<Button x:Name="btn_Color" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Height="25" Width="25" BorderBrush="Black">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="Black"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
I want this button to change color when I click it, and be able to reuse this code for other buttons. I will use the color later for other things so I need to be able to access that data.
I tried to add a PreviewMouseDown event to the Ellipse and change the property on (Ellipse)sender but I can't access the color of the Ellipse even if I add it a x:Name property. How can I achieve this? Thanks! :)
You can use this code to achieve what you want. It is at least a starting point:
<Button x:Name="btn_Color" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Height="25" Width="25">
<Button.Style>
<Style TargetType="Button">
<Setter Property="BorderBrush" Value="Black"/>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="BorderBrush" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{Binding BorderBrush, RelativeSource={RelativeSource AncestorType=Button}}"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
Doing it this way, you can then Bind the BorderBrush to a different color, or a DependencyProperty and change it from another place.
Can I group some Views of the same type so I'll be able to apply changes to all of them at once?
Something like writing in XAML:
<Image GroupName="imagesToScale"/>
<Image/>
<Image GroupName="imagesToScale"/>
<Image GroupName="imagesToScale"/>
And doing in C#:
imagesToScale.Scale = 1.5;
Is it possible? I need to do it one by one?
This is how you do in WPF XAML
<Style TargetType="Image" x:Key="scale">
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.5" ScaleY="1.5"> </ScaleTransform>
</Setter.Value>
</Setter>
</Style>
<Image Style="{StaticResource scale}" ></Image>