Hello I want to make a button with icon, using Rectangle:
<Style x:Key="CancelButton" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Content">
<Setter.Value>
<Rectangle>
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill">
<VisualBrush.Visual>
<Canvas Width="76.0106" Height="76.0106" Clip="F1 M 0,0L 76.0106,0L 76.0106,76.0106L 0,76.0106L 0,0">
<Path Width="34.8358" Height="32.9005" Canvas.Left="20.5862" Canvas.Top="20.5864" Stretch="Fill" Fill="{DynamicResource RedBrush}" Data="F1 M 25.3362,20.5864L 25.3348,29.2137C 28.5107,25.8499 33.0116,23.7507 38.0029,23.7507C 47.6232,23.7507 55.422,31.5494 55.422,41.1698C 55.422,45.9799 53.4723,50.3347 50.32,53.4869L 46.401,49.5679C 48.5503,47.4187 49.8796,44.4495 49.8796,41.1699C 49.8796,34.6106 44.5623,29.2932 38.003,29.2932C 34.4855,29.2932 31.3251,30.8224 29.1504,33.2522L 38.0029,33.2531L 33.2529,38.0031L 20.5862,38.0031L 20.5862,25.3364L 25.3362,20.5864 Z "/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.OpacityMask>
</Rectangle>
</Setter.Value>
</Setter>
</Style>
When I apply such style to the button, nothing happens. It doesn't work.
Am I doing anything wrong?
You should set the Width, Height and Fill properties of the Rectangle:
<Rectangle Width="76.0106" Height="76.0106" Fill="Gray">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill">
<VisualBrush.Visual>
<Canvas Width="76.0106" Height="76.0106" Clip="F1 M 0,0L 76.0106,0L 76.0106,76.0106L 0,76.0106L 0,0">
<Path Width="34.8358" Height="32.9005" Canvas.Left="20.5862" Canvas.Top="20.5864" Stretch="Fill" Fill="Red" Data="F1 M 25.3362,20.5864L 25.3348,29.2137C 28.5107,25.8499 33.0116,23.7507 38.0029,23.7507C 47.6232,23.7507 55.422,31.5494 55.422,41.1698C 55.422,45.9799 53.4723,50.3347 50.32,53.4869L 46.401,49.5679C 48.5503,47.4187 49.8796,44.4495 49.8796,41.1699C 49.8796,34.6106 44.5623,29.2932 38.003,29.2932C 34.4855,29.2932 31.3251,30.8224 29.1504,33.2522L 38.0029,33.2531L 33.2529,38.0031L 20.5862,38.0031L 20.5862,25.3364L 25.3362,20.5864 Z "/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.OpacityMask>
</Rectangle>
Related
I have stored some icons as XAML-Code in the resourcedictionary, e.g.
<DataTemplate x:Key="Question">
<Viewbox Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Rectangle Width="16" Height="16">
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M10,14L6,14 6,9C6,8.232,6.29,7.531,6.765,7L4,7 4,5C4,3.262 5.682,2 8,2 10.316,2 12,3.262 12,5L12,7C12,8.304,11.164,9.416,10,9.828z" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M9,11L7,11 7,13 9,13z M9,10L7,10 7,9C7,7.897,7.897,7,9,7L9,5.203C8.84,5.115 8.495,5 8,5 7.504,5 7.159,5.115 7,5.203L7,6 5,6 5,5C5,3.841 6.261,3 8,3 9.738,3 11,3.841 11,5L11,7C11,8.103,10.102,9,9,9z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Viewbox>
</DataTemplate>
The problem: width and height are fixed values. So i changed the fixed values to "Auto" without any error in the resourcedictionary.
<DataTemplate x:Key="QuestionAuto">
<Viewbox Width="Auto" Height="Auto" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Rectangle Width="Auto" Height="Auto">
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M10,14L6,14 6,9C6,8.232,6.29,7.531,6.765,7L4,7 4,5C4,3.262 5.682,2 8,2 10.316,2 12,3.262 12,5L12,7C12,8.304,11.164,9.416,10,9.828z" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M9,11L7,11 7,13 9,13z M9,10L7,10 7,9C7,7.897,7.897,7,9,7L9,5.203C8.84,5.115 8.495,5 8,5 7.504,5 7.159,5.115 7,5.203L7,6 5,6 5,5C5,3.841 6.261,3 8,3 9.738,3 11,3.841 11,5L11,7C11,8.103,10.102,9,9,9z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
</Viewbox>
</DataTemplate>
Then i used the icon in my view with setting the width and height values, but nothing is shown. the "fixed" icon works, the "auto" icon not.
<ContentPresenter Grid.RowSpan="2"
ContentTemplate="{StaticResource Question32}"
Margin="20,0">
</ContentPresenter>
vs.
<ContentPresenter Grid.RowSpan="2"
ContentTemplate="{StaticResource QuestionAuto}"
Margin="20,0"
Width="64"
Height="64">
</ContentPresenter>
Is it possible to set width and height parameter in the xaml-view and use them in the resourcedictionary? because the xaml-icon is basically "dynamic" and a variable size would be better than guessing the width and height to fit perfectly.
Better define the icons as DrawingImage resources like
<DrawingImage x:Key="Question">
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M10,14L6,14 6,9C6,8.232,6.29,7.531,6.765,7L4,7 4,5C4,3.262 5.682,2 8,2 10.316,2 12,3.262 12,5L12,7C12,8.304,11.164,9.416,10,9.828z" />
<GeometryDrawing Brush="#FF414141" Geometry="F1M9,11L7,11 7,13 9,13z M9,10L7,10 7,9C7,7.897,7.897,7,9,7L9,5.203C8.84,5.115 8.495,5 8,5 7.504,5 7.159,5.115 7,5.203L7,6 5,6 5,5C5,3.841 6.261,3 8,3 9.738,3 11,3.841 11,5L11,7C11,8.103,10.102,9,9,9z" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
and show them in an Image element like
<Image Source="{StaticResource Question}" Width="64" Height="64"/>
The drawing would stretch to the desired size according to the Stretch property of the Image, which defaults to Uniform.
I have a canvas and I set a background image to it. I have some rectangles within the canvas. When the form gets resized, the background image gets strechted but I also want the rectangles to get to the new positions. Any help?
<Window x:Class="abc.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:jas="clr-namespace:foo"
Title="foo" Width="1200" Height="800" >
<jas:DragCanvas x:Name="jasCanvas" >
<jas:DragCanvas.Background>
<DrawingBrush Stretch="None" TileMode="Tile" Viewport="0,0,20,20" ViewportUnits="Absolute">
<!-- a drawing of 4 checkerboard tiles -->
<DrawingBrush.Drawing>
<DrawingGroup>
<!-- checkerboard background -->
<!--<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,20,20" />
</GeometryDrawing.Geometry>
</GeometryDrawing>-->
<!-- two checkerboard foreground tiles -->
<!--<GeometryDrawing Brush="LightGray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,10,10" />
<RectangleGeometry Rect="10,10,10,10" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>-->
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</jas:DragCanvas.Background>
<TextBlock x:Name="m_resultText" FontSize="16" Canvas.Left="10" Canvas.Top="10"
jas:DragCanvas.CanBeDragged="False"
FontWeight="Bold"
Background="Black"/>
<Rectangle x:Name="m_redRect" Width="40" Height="120" Canvas.Left="100" Canvas.Top="50" Stroke="Gray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
StrokeThickness="1" >
<Rectangle.Fill>
<!--<SolidColorBrush Color="#99FF0000"/>-->
<ImageBrush ImageSource="Media/yacht.png" />
</Rectangle.Fill>
<Rectangle.RenderTransform>
<RotateTransform x:Name="m_redRectRotate" Angle="0" CenterX="20" CenterY="60"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="m_greenRect" Width="40" Height="120" Canvas.Left="247" Canvas.Top="113" Stroke="Gray"
StrokeThickness="1"
>
<Rectangle.Fill>
<!--<SolidColorBrush Color="#9900FF00" />-->
<ImageBrush ImageSource="Media/yacht.png"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<RotateTransform x:Name="m_greenRectRotate" Angle="0" CenterX="20" CenterY="60"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="m_greenRect2" Width="40" Height="120" Canvas.Left="338" Canvas.Top="113" Stroke="Gray"
StrokeThickness="1"
>
<Rectangle.Fill>
<!--<SolidColorBrush Color="#9900FF00" />-->
<ImageBrush ImageSource="Media/yacht.png"/>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<RotateTransform x:Name="m_greenRectRotate2" Angle="0" CenterX="20" CenterY="60"/>
</Rectangle.RenderTransform>
</Rectangle>
<Button Content="Button" Canvas.Left="464" Canvas.Top="10" Width="75" Click="Button_Click" x:Name="buton" jas:DragCanvas.CanBeDragged="false"/>
</jas:DragCanvas>
</Window>
here is the background image set :
ImageBrush ib = new ImageBrush();
ib.ImageSource = new BitmapImage(new Uri(#"Media\foo.jpg", UriKind.Relative));
jasCanvas.Background = ib;
There is a very simple solution that you can use... just put your Canvas inside a ViewBox control. From the linked page on MSDN, the ViewBox Defines a content decorator that can stretch and scale a single child to fill the available space:
<ViewBox Stretch="Fill">
<jas:DragCanvas x:Name="jasCanvas">
...
</jas:DragCanvas>
</ViewBox>
If it doesn't work straight out of the box, then just experiment with the Stretch and StretchDirection properties.
I'm not sure about your jas namespace, but there is no layout system support in standard Canvas panel. So if you want something placed inside canvas to move and resize automatically due to parent canvas position change you have to create some code for this behavior manually.
Modify your XAML code like this:
<jas:DragCanvas x:Name="jasCanvas" SizeChanged="jasCanvas_SizeChanged">
And then in your code behind file:
private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
var deltaWidth = (e.NewSize.Width - e.PreviousSize.Width);
m_redRect.Width += deltaWidth;
// and so on
}
I have an user control like this.
Button
Viewbox
ContentPresenter
Grid
Path
I need to change Button.Viewbox.Grid.Path.Fill color.
Is there any way to do this?
My Style.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="PathStyle" TargetType="{x:Type Viewbox}">
<!-- ?????????????????? -->
</Style>
I tried this
<Button>
<Viewbox Width="18" Height="18" Style="{DynamicResource PathStyle}">
<ContentPresenter Content="{Binding Converter={StaticResource uriToUIElementConverter}, ConverterParameter=Images/New.xaml}"></ContentPresenter>
</Viewbox>
</Button>
New.Xaml
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="newDocument" Fill="#FF000000" Stretch="Fill">
<Path.Data>
<PathGeometry FillRule="Nonzero" Figures="M43,30L50.75,30 43,22.25 43,30z M52,34L39,34 39,21 24,21 24,45 20,45 20,17 43.25,17 56,29.75 56,59 34,59 34,55 52,55 52,34z M28,38L33,38 33,46 41,46 41,51 33,51 33,59 28,59 28,51 20,51 20,46 28,46 28,38z M20,59L20,52 24,52 24,55 27,55 27,59 20,59z" />
</Path.Data>
</Path>
</Grid>
Uhm,
<Path Fill="Red" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="newDocument" Stretch="Fill">
<Path.Data>
<PathGeometry FillRule="Nonzero" Figures="M43,30L50.75,30 43,22.25 43,30z M52,34L39,34 39,21 24,21 24,45 20,45 20,17 43.25,17 56,29.75 56,59 34,59 34,55 52,55 52,34z M28,38L33,38 33,46 41,46 41,51 33,51 33,59 28,59 28,51 20,51 20,46 28,46 28,38z M20,59L20,52 24,52 24,55 27,55 27,59 20,59z" />
</Path.Data>
</Path>
?
I'm trying to display available Wifi networks (using ManagedWifi SDK) on a listview.
I have defined ObservableCollection of WifiNetwork (contains name, type, signal Strength(int) etc) in my viewmodel as shown below
public ObservableCollection<WifiNetwork> AvailableNetworks { get; set; }
I have defined Control templates (like 1 green bar and 4 white bars to indicate signal strength <= 20%, 2 green bars and 3 white bars to indicate signal strength between 20 to 40% etc) in Application Resources in app.xaml as shown below
<ControlTemplate x:Key="Signal1">
<Canvas Width="32" Height="32" Canvas.Left="0" Canvas.Top="0">
<Rectangle Width="5.4375" Height="11.375" Canvas.Left="0.0937499" Canvas.Top="20.6563" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/>
<Rectangle Width="6.40625" Height="16" Canvas.Left="5.34375" Canvas.Top="16.0313" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
<Path Width="6.88835" Height="21.6562" Canvas.Left="11.75" Canvas.Top="10.375" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z "/>
<Rectangle Width="6.78126" Height="26.9687" Canvas.Left="18.5625" Canvas.Top="5.09376" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
<Rectangle Width="6.71874" Height="31.8437" Canvas.Left="25.2812" Canvas.Top="0.250002" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
</Canvas>
</ControlTemplate>
<ControlTemplate x:Key="Signal2">
<Canvas Width="32" Height="32" Canvas.Left="0" Canvas.Top="0">
<Rectangle Width="5.4375" Height="11.375" Canvas.Left="0.0937499" Canvas.Top="20.6563" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/>
<Rectangle Width="6.40625" Height="16" Canvas.Left="5.34375" Canvas.Top="16.0313" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/>
<Path Width="6.88835" Height="21.6562" Canvas.Left="11.75" Canvas.Top="10.375" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z "/>
<Rectangle Width="6.78126" Height="26.9687" Canvas.Left="18.5625" Canvas.Top="5.09376" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
<Rectangle Width="6.71874" Height="31.8437" Canvas.Left="25.2812" Canvas.Top="0.250002" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
</Canvas>
</ControlTemplate>
Now I need to return this control template from my view model to bind it to a button to show the appropriate signal strength in my listBox.
I probably need to have some kind of conversion from Signal Strength (int) to Control template.
Any suggestions / code examples to achieve this task?
This should guide to right direction:
<ItemsControl ItemsSource="{Binding AvailableNetworks }">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="20" Height="{Binding SignalStrength,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Fill="{Binding Color,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I like Darek's answer, but if you really want to use control templates like this, you should use a style and a data trigger bound to the signal strength, e.g.:
<Style TargetType="{x:Type MyControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding SignalStrength}" Value="1">
<Setter Property="ControlTemplate" Value="{StaticResource Signal1}"/>
</DataTrigger>
<DataTrigger Binding="{Binding SignalStrength}" Value="2">
<Setter Property="ControlTemplate" Value="{StaticResource Signal2}"/>
</DataTrigger>
<!-- and so on -->
</Style.Triggers>
</Style>
Another approach would be to just use a ItemTemplate on your listbox and to create a converter class.
Create a public class called ColorConverter and use the following code in it:
public class ColorConverter : IValueConverter
{
#region Implementation of IValueConverter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
var val = System.Convert.ToInt32(value.ToString());
var param = System.Convert.ToInt32(parameter.ToString());
return val >= param ? Brushes.Green : Brushes.White;
}
catch
{
return Brushes.White;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Then on the page with the ListBox assign the converter:
<Window.Resources>
<Converters:ColorConverter x:Key="colorConverter" />
</Window.Resources>
Make sure you put the namespace for "Converters" at the top of the xaml:
xmlns:Converters="clr-namespace:ProjectNameHere"
Then create a DataTemplate on your listbox using your code above, substituting the bindings to the correct forms:
<ListBox Margin="0,73,0,0" ItemsSource="{Binding AvailableNetworks}">
<ListBox.ItemTemplate>
<DataTemplate>
<Canvas Width="32"
Height="32"
Canvas.Left="0"
Canvas.Top="0">
<Rectangle Width="5.4375"
Height="11.375"
Canvas.Left="0.0937499"
Canvas.Top="20.6563"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=0}" />
<Rectangle Width="6.40625"
Height="16"
Canvas.Left="5.34375"
Canvas.Top="16.0313"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=20}" />
<Path Width="6.88835"
Height="21.6562"
Canvas.Left="11.75"
Canvas.Top="10.375"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=40}"
Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z " />
<Rectangle Width="6.78126"
Height="26.9687"
Canvas.Left="18.5625"
Canvas.Top="5.09376"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=60}" />
<Rectangle Width="6.71874"
Height="31.8437"
Canvas.Left="25.2812"
Canvas.Top="0.250002"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=80}" />
</Canvas>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The down side to doing it this way is the lack of style reuse, unlike the other methods mentioned.
I have the following simple path. But everytime in Expression Blend I try and set a translate transform to its image brush the image disappears. Ideally the fill should be none. I need to dynamicly set the x and y of the image within the brush if possible. If you have done this in C# that would be fine as well. Or am I mistaken and this just cant be done?
<Path Data="M0.5,0.5 L99.5,0.5 L99.5,439.5 L0.5,439.5 z" Fill="#BFF31313" Height="440" Canvas.Left="192" Stretch="Fill" Stroke="Black" Canvas.Top="176" Width="100" Visibility="Collapsed">
<Path.Fill>
<ImageBrush ImageSource="4x4.png" Stretch="None"/>
</Path.Fill>
</Path>
Something like this?
<Path Data="M0.5,0.5 L99.5,0.5 L99.5,439.5 L0.5,439.5 z" Fill="#BFF31313" Height="440" Canvas.Left="192" Stretch="Fill" Stroke="Black" Canvas.Top="176" Width="100" Visibility="Collapsed">
<Path.Fill>
<ImageBrush ImageSource="4x4.png" Stretch="None">
<ImageBrush.Transform>
<TranslateTransform X="10" Y="10"/>
</ImageBrush.Transform>
</ImageBrush>
</Path.Fill>
</Path>