سؤال

أقوم بإنشاء مكتب ألعاب. كنت أرغب في تحديد حجم الحقل (حقل واحد هو مربع) كخاصية مرفقة ومع قيمة مجموعة البيانات هذه التي من شأنها أن ترسم مصفوفة 2 × 2 (وسيقوم وضع البلاط بباقي مكتب اللعبة).

أنا في خسارة تمامًا ما هو الخطأ لأن الربط لا يعمل.

خط الاختبار في XAML للسلوك الذي أود الحصول عليه:

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

يعتمد مكتب اللعبة على هذه العينة من الرسم: http://msdn.microsoft.com/en-us/library/aa970904.aspx (صورة هنا)

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>

تعريف المحول والممتلكات:

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();
        }
    }
}
هل كانت مفيدة؟

المحلول

TemplateBindings فقط العمل لخصائص التبعية المحددة على التحكم الذي يتم تنظيمه (في أ ControlTemplate). تحتاج فقط إلى تبديل هذا حوله ليكون Binding مع RelativeSource من AncestorType (أيضًا ، تتطلب الخصائص المرفقة استخدام قوسين في الربط):

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

يحرر تحديث RelativeSource ملزمة ، لأنه لم يتم تعريفه داخل أ ControlTemplate.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top