I'm trying to set the "Stroke" property of Path in my visual brush (Defined in App.xaml) via the property from my model. I'm using this style in my another control template in a usercontrol.
Style in User control resources:
<Ellipse x:Name="slideThumb" Height="25" Width="25" Stroke="{Binding ThumbColor, UpdateSourceTrigger=PropertyChanged}">
<Ellipse.Style>
<Style TargetType="{x:Type Ellipse}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHatchBrush}" Value="true">
<Setter Property="Fill" Value="{StaticResource HatchBrushVertical}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsHatchBrush}" Value="false">
<Setter Property="Fill" Value="{Binding ThumbColor, UpdateSourceTrigger=PropertyChanged}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
Brush Defined in App.xaml:
<VisualBrush x:Key="HatchBrushVertical" TileMode="Tile" Viewport="0,0,2,3" ViewportUnits="Absolute" Viewbox="0,0,5,5" ViewboxUnits="Absolute">
<VisualBrush.Transform>
<RotateTransform Angle="45" />
</VisualBrush.Transform>
<VisualBrush.Visual>
<Canvas>
<Path Data="M 0 0 L 0 10" Stroke="{Binding Path=Stroke, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Ellipse}}}" StrokeThickness="5"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
Problem here is, I'm not able to set the Stroke property of the visal brush in app.xaml through the binding.
Need help. Thanks in advance
You may perhaps use the Brush as an OpacityMask.
First, create a (simpler) DrawingBrush instead of a VisualBrush:
<DrawingBrush x:Key="HatchBrush" TileMode="Tile"
Viewport="0,0,3,3" ViewportUnits="Absolute"
Viewbox="0,0,2,2" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing Geometry="M-1,2 L2,-1 M0,3 L3,0">
<GeometryDrawing.Pen>
<Pen Thickness="0.7" Brush="Black"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
Then write a DataTrigger like this:
<DataTrigger Binding="{Binding IsHatchBrush}" Value="True">
<Setter Property="OpacityMask" Value="{StaticResource HatchBrush}" />
</DataTrigger>
Related
Is there a way to scale an svg image inserted using DrawingBrush as in the following code?
<Style x:Key="HamburgerMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource MenuItemControlTemplate1}"/>
<Setter Property="Icon">
<Setter.Value>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Geometry="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z"
Brush="Red"/>
</DrawingImage.Drawing>
</DrawingImage>
</Setter.Value>
</Setter>
</Style>
According to your description, I think you should code as below:
<Style x:Key="HamburgerMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource MenuItemControlTemplate1}"/>
<Setter Property="Icon">
<Setter.Value>
<Image Stretch="UniformToFill" Width="auto" Height="auto" HorizontalAlignment="Left">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Geometry="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z" Brush="Red"/>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Setter.Value>
</Setter>
</Style>
Note:
Since I didn't have the Template property, I removed it. If you have problems displaying the icon despite this property, you should check it.
Also, if you are not sensitive to the use of Drawing Image, you can use the Path tag
<Path Stretch="Fill" Height="30" Width="30" Data="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z" Fill="Red"></Path>
I need to create List View, which would be displaying like data-grid. (Data will be displaying in columns).
Also needs to perform it without GridView, definitely without column names on top. My current code:
<Rectangle Width="18" Margin="6,2,0,2"
Height="14" Fill="{DynamicResource AccentColorBrush}" >
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{DynamicResource appbar_nfc}" />
</Rectangle.OpacityMask>
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}},
Path=IsSelected}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<TextBlock Margin="0 0 0 0"
HorizontalAlignment="Right"
Grid.Column="2">
Album Title
</TextBlock>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
That's what I have for now -
But I need to place "Album Title" from previous page like names there -
But without column names on top.
Thanks.
I have got a style as follows.
<TextBox HorizontalContentAlignment="Center" Text="{Binding IpAddress, Mode=TwoWay}" ToolTip="Ip Address of camera">
<TextBox.Style>
<Style TargetType="TextBox" xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush" AlignmentX="Center" AlignmentY="Center" Stretch="None">
<VisualBrush.Visual>
<Label Content="Camera Ip Address" Foreground="Gray" Opacity="0.5" FontStyle="Italic" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
And I had kept it as a resource dictionary in a Skin.xaml file to be re-used as explained in the answer here.
But now I want the Content="Camera Ip Address" (the 7th line in the style) to be different for each textbox that I apply the style to. I saw SO answers this and this. These SO answers are suggesting the BasedOn attribute, but I am not sure how to apply this to my case. My case seems to be many levels deep. Can someone please suggest me how to achieve this.
Basically what I want is, for one textbox that I apply the Content should be Camera Ip Address, while for another textbox I want this content to be Camera Login. How do I achieve this?
You can set the content of that inner Label to the Tag property of the TextBox and then display it in the Label.
Like so:
<TextBox Tag="Whatever you want">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush">
<VisualBrush.Visual>
<Label Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=TextBox},Path=Tag,Mode=OneWay" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
</Style>
</TextBox.Style>
</TextBox>
I have search hint textbox
<TextBox
TextChanged="textboxsearch_TextChanged"
Grid.Column="4" Margin="0,0,10,10" Height="22" >
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource SearchHint}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
</TextBox.Style>
</TextBox>
here is SearchHint style
<VisualBrush x:Key="SearchHint" Stretch="None">
<VisualBrush.Visual>
<TextBox FontStyle="Italic" Background="White" Foreground="Gray" Text="Enter search text…" />
</VisualBrush.Visual>
</VisualBrush>
The search box back ground is filled by the searchhint style. The problem I have now is how can I make the width of the visual brush fill the size of the textbox. Right now it fills only a portion of the textbox.
The Text="Enter search text…" has a white background but the rest of the textbox is gray. I wanted to have a white background with gray hint text.
Give the TextBox in the VisualBrush a large padding (to the right), and give the VisualBrush a left alignment:
<VisualBrush x:Key="SearchHint" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBox FontStyle="Italic" Background="White" Foreground="Gray" Text="Enter search text…"
Padding="0,0,1000,0" />
</VisualBrush.Visual>
</VisualBrush>
Well for what you're trying you can bind the Width of the control in the VisualBrush to your actual target's ActualWidth
something like:
<VisualBrush x:Key="SearchHint"
Stretch="None">
<VisualBrush.Visual>
<TextBox Background="White"
FontStyle="Italic"
Foreground="Gray"
Width="{Binding ElementName=tb, Path=ActualWidth}"
Height="{Binding ElementName=tb, Path=ActualHeight}"
Text="Enter search text…" />
</VisualBrush.Visual>
</VisualBrush>
...
<TextBox Grid.Column="4"
Height="22"
TextChanged="textboxsearch_TextChanged"
x:Name="tb"
Margin="0,0,10,10">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text"
Value="">
<Setter Property="Background"
Value="{StaticResource SearchHint}" />
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="Background"
Value="White" />
</Trigger>
</Style.Triggers>
<Setter Property="VerticalAlignment"
Value="Bottom" />
</Style>
</TextBox.Style>
</TextBox>
However
What you're "functionally" trying to do is referred to commonly as "Watermark" / "Placeholder text" and it's much simpler to use that approach than have a complicated VisualBrush with an actual control being turned into a Brush. Just my opinion.
If you want to try the Watermark approach This Answer gives a good example for you to work with.
I'd like to know if it's possible to do the following:
create a black and white image, say of a dog
add the image to a button as a mask
change the style using (data) triggers, e.g. disabled - the dog is grey, "loading" - the dog is red, "ready" the dog is yellow, etc.
Basically I want to create button icons using pixels but be able to set the color at runtime depending on triggers. Something like this:
After 2 hours of googling here's the answer
<Window x:Class="IconTest.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>
<!-- button style -->
<Style x:Key="ToolButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Width="16" Height="16" Background="#ffbbbbbb">
<Rectangle Name="rect" Fill="Black" OpacityMask="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="rect" Property="Fill" Value="Green" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="rect" Property="Fill" Value="Yellow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Width="16" Height="16" Style="{StaticResource ToolButton}">
<ImageBrush ImageSource="/test.png"/>
</Button>
</Grid>
</Window>
You can define an OpacityMask for the Button. I believe you will be able to add triggers (if you need them) to change the Background of Button.
Sample:
<Button Height="100" Width="100" Background="Green">
<Button.OpacityMask>
<DrawingBrush AlignmentX="Left" AlignmentY="Top">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#33000000">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,40,40" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="#FF000000">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="10,10,20,20">
<RectangleGeometry.Transform>
<RotateTransform Angle="45" CenterX="20" CenterY="20" />
</RectangleGeometry.Transform>
</RectangleGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Button.OpacityMask>
</Button>
In my opinion, you don't need create image mask in WPF to achieve your requirement. You could simply edit the control template of the button class.
Please refer to the Ellipse button example in this page. Control Template
Then you could simply change the Fill Color of that shape using trigger. Trigger
Cheers,