I'm creating a game desk. I wanted to specify field size (one field is a square) as a attached property and with this data set value of ViewPort which would draw 2x2 matrix (and tile mode would do the rest of game desk).
I'm quite at loss what is wrong because the binding doesn't work.
Testing line in XAML for the behaviour I would like to have:
<DrawingBrush Viewport="0,0,100,100" ViewportUnits="Absolute" TileMode="None">
The game desk is based on this sample of DrawingPaint: http://msdn.microsoft.com/en-us/library/aa970904.aspx (an image is here)
XAML:
<Window x:Class="Sokoban.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Sokoban"
Title="Window1" Height="559" Width="419">
<Window.Resources>
<local:FieldSizeToRectConverter x:Key="fieldSizeConverter" />
<Style x:Key="GameDesk" TargetType="{x:Type Rectangle}">
<Setter Property="local:GameDeskProperties.FieldSize" Value="50" />
<Setter Property="Fill">
<Setter.Value>
<!--<DrawingBrush Viewport="0,0,100,100" ViewportUnits="Absolute" TileMode="None">-->
<DrawingBrush Viewport="{TemplateBinding local:GameDeskProperties.FieldSize, Converter={StaticResource fieldSizeConverter}}" ViewportUnits="Absolute" TileMode="None">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="CornflowerBlue">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,100,100" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="Azure">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,50,50" />
<RectangleGeometry Rect="50,50,50,50" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Rectangle Style="{StaticResource GameDesk}" Width="300" Height="150" />
</StackPanel>
</Window>
Converter and property definition:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Diagnostics;
using System.Windows.Data;
namespace Sokoban
{
public class GameDeskProperties : Panel
{
public static readonly DependencyProperty FieldSizeProperty;
static GameDeskProperties()
{
PropertyChangedCallback fieldSizeChanged =
new PropertyChangedCallback(OnFieldSizeChanged);
PropertyMetadata fieldSizeMetadata =
new PropertyMetadata(50, fieldSizeChanged);
FieldSizeProperty = DependencyProperty.RegisterAttached("FieldSize",
typeof(int), typeof(GameDeskProperties), fieldSizeMetadata);
}
public static int GetFieldSize(DependencyObject target)
{
return (int)target.GetValue(FieldSizeProperty);
}
public static void SetFieldSize(DependencyObject target, int value)
{
target.SetValue(FieldSizeProperty, value);
}
static void OnFieldSizeChanged(DependencyObject target,
DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("FieldSize just changed: " + e.NewValue);
}
}
[ValueConversion(/* sourceType */ typeof(int), /* targetType */ typeof(Rect))]
public class FieldSizeToRectConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Debug.Assert(targetType == typeof(int));
int fieldSize = int.Parse(value.ToString());
return new Rect(0, 0, 2 * fieldSize, 2 * fieldSize);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// should not be called in our example
throw new NotImplementedException();
}
}
}