Is it possible to use WPF ResourceDictionary with parameters? - c#

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.

Related

Creating button content, using rectangle's OpacityMaskProperty

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>

Binding to Generic UI Element / XAML Interface

I have a DrawingImage that I use as a Vector image placeholder.
Further on, there are styles that take that respective DrawingImage and use it as an image in my UserControl custom button.
So far everything was fine, but I just came to realize that my current approach has caused my DrawingImages to be non-reusable, since they have their Brush property hard-bound to the control, they are used in, as follows:
<DrawingImage x:Key="addIcon">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="{Binding Path=ImageBrush, ElementName=addButton}" Geometry="M438.2,0H51.6C23.1,0,0,23.2,0,51.6v386.6c0,28.5,23.2,51.6,51.6,51.6h386.6c28.5,0,51.6-23.2,51.6-51.6V51.6
C489.8,23.2,466.6,0,438.2,0z M465.3,438.2c0,14.9-12.2,27.1-27.1,27.1H51.6c-14.9,0-27.1-12.2-27.1-27.1V51.6
c0-14.9,12.2-27.1,27.1-27.1h386.6c14.9,0,27.1,12.2,27.1,27.1V438.2z" />
<GeometryDrawing Brush="{Binding Path=ImageBrush, ElementName=addButton}" Geometry="M337.4,232.7h-80.3v-80.3c0-6.8-5.5-12.3-12.3-12.3s-12.3,5.5-12.3,12.3v80.3h-80.3c-6.8,0-12.3,5.5-12.3,12.2
c0,6.8,5.5,12.3,12.3,12.3h80.3v80.3c0,6.8,5.5,12.3,12.3,12.3s12.3-5.5,12.3-12.3v-80.3h80.3c6.8,0,12.3-5.5,12.3-12.3
C349.7,238.1,344.2,232.7,337.4,232.7z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
Now, I was trying to come up with a way to have them bound not directly to the Element, but to some kind of a generic Element (similairly as interfaces work) so that the code would be sure that anything that is bound to it, has got the Brush Dependency property.
So far, i failed to find it.
I have also tried by searching through an ancestor, still no luck.
Is there a more or less common practice to binding to unknown Elements, that have certain dependency properties, without exposing them directly?
In fact, there is no way to do directly what you ask. The reason is that when you define DrawingImage as a resource and then use it as a source for image, then no copies of the resource are created, but instead of this each image looks at the same resource. Therefore, the DrawingImage can not have a parent in the visual tree at all, so there is just no control to bind to.
There are two options here. One is to use a Geometry as a resource, not a DrawingImage. Then you can create some DrawingImage resources referencing to this Geometry and using different colors. Or do not use DrawingImage at all, but use the Geometry directly (for example, through the Path). Actually, there are so many ways how to use and combine Geometry resources. I give just few examples here:
<Window x:Class="FlipControlApp.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"
Title="MainWindow" Height="300" Width="300">
<Window.Resources>
<PathGeometry x:Key="addIconGeometry" Figures="M337.4,232.7h-80.3v-80.3c0-6.8-5.5-12.3-12.3-12.3s-12.3,5.5-12.3,12.3v80.3h-80.3c-6.8,0-12.3,5.5-12.3,12.2
c0,6.8,5.5,12.3,12.3,12.3h80.3v80.3c0,6.8,5.5,12.3,12.3,12.3s12.3-5.5,12.3-12.3v-80.3h80.3c6.8,0,12.3-5.5,12.3-12.3
C349.7,238.1,344.2,232.7,337.4,232.7z"/>
<PathGeometry x:Key="iconBorderGeometry" Figures="M438.2,0H51.6C23.1,0,0,23.2,0,51.6v386.6c0,28.5,23.2,51.6,51.6,51.6h386.6c28.5,0,51.6-23.2,51.6-51.6V51.6
C489.8,23.2,466.6,0,438.2,0z M465.3,438.2c0,14.9-12.2,27.1-27.1,27.1H51.6c-14.9,0-27.1-12.2-27.1-27.1V51.6
c0-14.9,12.2-27.1,27.1-27.1h386.6c14.9,0,27.1,12.2,27.1,27.1V438.2z"/>
<GeometryGroup x:Key="addIconWithBorderGeometry">
<StaticResource ResourceKey="iconBorderGeometry"/>
<StaticResource ResourceKey="addIconGeometry"/>
</GeometryGroup>
<DrawingImage x:Key="addIconBlack">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Black" Geometry="{StaticResource addIconWithBorderGeometry}" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Window.Resources>
<UniformGrid Columns="2">
<Button Name="addButton0" Width="100" Height="100">
<Image Source="{StaticResource addIconBlack}"/>
</Button>
<Button Width="100" Height="100" Foreground="Blue">
<Image>
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Control}}"
Geometry="{StaticResource addIconGeometry}" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Button>
<Button Width="100" Height="100" Foreground="Green">
<Grid>
<Path Data="{StaticResource iconBorderGeometry}" Fill="Pink" Stretch="Uniform"/>
<Path Data="{StaticResource addIconGeometry}" Fill="Purple" Stretch="Uniform" Margin="15"/>
</Grid>
</Button>
<Button x:Name="addBtn" Width="100" Height="100" Foreground="Green">
<Path Fill="{Binding Foreground, ElementName=addBtn}" Stretch="Uniform">
<Path.Data>
<CombinedGeometry Geometry1="{StaticResource iconBorderGeometry}" Geometry2="{StaticResource addIconGeometry}"/>
</Path.Data>
</Path>
</Button>
</UniformGrid>
</Window>
Another option is to use whole Image as resource with a Brush binding to the some ancestors property. But in this case, it is necessary to use the attribute x:Shared and hence the resource must be declared in the compiled resource dictionary (for details see x:Shared).
Create resource:
<ResourceDictionary>
<Image x:Key="addIconImage2" x:Shared="False">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Control}}"
Geometry="M438.2,0H51.6C23.1,0,0,23.2,0,51.6v386.6c0,28.5,23.2,51.6,51.6,51.6h386.6c28.5,0,51.6-23.2,51.6-51.6V51.6
C489.8,23.2,466.6,0,438.2,0z M465.3,438.2c0,14.9-12.2,27.1-27.1,27.1H51.6c-14.9,0-27.1-12.2-27.1-27.1V51.6
c0-14.9,12.2-27.1,27.1-27.1h386.6c14.9,0,27.1,12.2,27.1,27.1V438.2z" />
<GeometryDrawing Brush="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Control}}"
Geometry="M337.4,232.7h-80.3v-80.3c0-6.8-5.5-12.3-12.3-12.3s-12.3,5.5-12.3,12.3v80.3h-80.3c-6.8,0-12.3,5.5-12.3,12.2
c0,6.8,5.5,12.3,12.3,12.3h80.3v80.3c0,6.8,5.5,12.3,12.3,12.3s12.3-5.5,12.3-12.3v-80.3h80.3c6.8,0,12.3-5.5,12.3-12.3
C349.7,238.1,344.2,232.7,337.4,232.7z" />
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</ResourceDictionary>
Then use it:
<Button Name="addButton3" Width="100" Height="100"
Content="{StaticResource addIconImage}" Foreground="Red"/>
<Button Name="addButton4" Width="100" Height="100"
Content="{StaticResource addIconImage}" Foreground="Green"/>
Each time you reference to it, new copy will be created.
But the first way is more flexible.

How to handle events in Custom Controls

I am trying to create a simple controller, here is my Generic.xaml;
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TopluNotEkle">
<Style TargetType="{x:Type local:FileSelector}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:FileSelector}">
<Button BorderThickness="8,8,8,8" Background="Gray" x:Name="MainButton">
<Button.BorderBrush>
<DrawingBrush TileMode="Tile" Viewport="0,0,64,64" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="LightGray">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="DarkGray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,50,50"/>
<RectangleGeometry Rect="50,50,50,50"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Button.BorderBrush>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="BlueViolet" FontWeight="Bold" FontSize="20">Drag & Drop</TextBlock>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
and this is my code behind
public class FileSelector : Control
{
static FileSelector()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FileSelector), new FrameworkPropertyMetadata(typeof(FileSelector)));
MainButton.Drop += myDrop;
}
static void myDrop(object sender, DragEventArgs e)
{
Debug.Fail("This is called");
}
}
I am getting The name MainButton does not exist in current context error. I also tried setting Drop = "myDrop", however, that also didn't work.
How can I listen to events on my component?
Buttons have been assigned a name by the x:Name attribute for us to be able to find them in code and hook up their click event handlers. This is done by overriding the OnApplyTemplate in our Custom Control class.
Retrieve the Button from the template
public override void OnApplyTemplate()
{
Button mainButton = GetTemplateChild("MainButton") as Button;
if (mainButton != null)
mainButton.Click += MainBtnClick;
}
Follow a complete tutorial like for example (but not necessarily) this: http://blog.magnusmontin.net/2013/03/16/how-to-create-a-custom-window-in-wpf/
So your problem is not what you are setting as a 'Drop' value, it is the reference to the MainButton that is not available.
I think you are trying to create a custom control, which typically defined as UserControl, not as a part of ResourceDictionary. I might be wrong as I haven't worked with WPF for several years. Here is how to create user control:
<UserControl x:class= "YourNamespace.FileSelector" ... other xmlns garbage>
<Button BorderThickness="8,8,8,8" Background="Gray" x:Name="MainButton">
<Button.BorderBrush>
<DrawingBrush TileMode="Tile" Viewport="0,0,64,64" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="LightGray">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="DarkGray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,50,50"/>
<RectangleGeometry Rect="50,50,50,50"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Button.BorderBrush>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="BlueViolet" FontWeight="Bold" FontSize="20">Drag & Drop</TextBlock>
</Button>
Also check out this tutorial: https://www.tutorialspoint.com/wpf/wpf_custom_controls.htm

Not able to draw horizontal line on canvas if the value of x2 is more than 125020

I'm trying to draw lines on a canvas but i'm not able to draw it if the value of x2 is more than 125020. Please find the XAML code below.`I'm able to see lines if the value of x2 is equal to or below 125020.
<ScrollViewer Name="C1_S" Grid.Row="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Bottom" Grid.ColumnSpan="2" >
<Canvas Name="canvas_core0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="640" Width="1000000" MouseWheel="Canvas_MouseWheel" >
<Line Stroke="Black" X1="20" Y1="20" X2="20" Y2="620" StrokeEndLineCap="Triangle" StrokeDashCap="Triangle" />
<Line Stroke="Black" X1="20" Y1="220" X2="125021" Y2="220" StrokeEndLineCap="Triangle" StrokeDashCap="Triangle" />
<Line Stroke="Black" X1="20" Y1="420" X2="{Binding ElementName=canvas_core0, Path=Width}" Y2="420" StrokeEndLineCap="Triangle" StrokeDashCap="Triangle" />
<Line Stroke="Black" X1="20" Y1="620" X2="{Binding ElementName=canvas_core0, Path=Width}" Y2="620" StrokeEndLineCap="Triangle" StrokeDashCap="Triangle" />
<Canvas.Background>
<DrawingBrush TileMode="Tile" Viewport="0,20,40,40" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,50,50"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Gray" Thickness=".1"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
<Canvas.RenderTransform>
<MatrixTransform/>
</Canvas.RenderTransform>
</Canvas>
</ScrollViewer>
Can anyone help? Is there any limit for the length of a line while drawing on a canvas?
Huh, must be a bug with WPF drawing long horizontal lines.
I don't have a real answer for you but a work around might be to NOT draw horizontal lines. Instead draw nearly horizontal lines. If you change Y1 or Y2, but not both, from "220" to "220.00001" then the line is visible. Note that "220.000001" (one more 0) did not draw so that seems to be another limit of some sort.
I tested it with X2="125021000" (added three 0s) and the line still showed up.
Increasing the StrokeThickness (even only slightly) works.
I realise this answer is somewhat unsatisfactory but may help if you are desperate and is at least a clue.
I tried playing with UseLayoutRounding and SnapsToDevicePixels but couldn't make it work.
Interesting.

WPF rectangle anchor

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
}

Categories