Pergunta

Estou criando uma mesa de jogos.Eu queria especificar o tamanho do campo (um campo é um quadrado) como uma propriedade anexada e com esse valor do conjunto de dados do ViewPort que desenharia a matriz 2x2 (e o modo bloco faria o resto da mesa de jogo).

Não sei o que há de errado porque a ligação não funciona.

Testando linha em XAML para o comportamento que eu gostaria de ter:

<DrawingBrush Viewport="0,0,100,100" ViewportUnits="Absolute" TileMode="None">

A mesa do jogo é baseada neste exemplo do DrawingPaint: http://msdn.microsoft.com/en-us/library/aa970904.aspx (uma imagem está aqui)

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>

Conversor e definição de propriedade:

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();
        }
    }
}
Foi útil?

Solução

TemplateBindings funciona apenas para propriedades de dependência definidas no controle que está sendo modelado (em um ControlTemplate).Você só precisa mudar isso para ser um Binding com um RelativeSource de AncestorType (além disso, as propriedades anexadas exigem o uso de parênteses em uma ligação):

...
<DrawingBrush Viewport="{Binding Path=(local:GameDeskProperties.FieldSize), Converter={StaticResource fieldSizeConverter}, RelativeSource={RelativeSource AncestorType={x:Type Rectangle}}}"
...

Editar Atualizado o RelativeSource vinculativo, pois não foi definido dentro de um ControlTemplate.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top