2010-04-06 17 views
7

Ich erstelle eine Spielkonsole. Ich wollte die Feldgröße (ein Feld ist ein Quadrat) als angefügte Eigenschaft und mit diesem Datensatzwert von ViewPort angeben, der 2x2-Matrix zeichnen würde (und der Kachelmodus würde den Rest von Game Desk erledigen).TemplateBinding mit Converter - was ist los?

Ich bin ziemlich Verlust, was falsch ist, weil die Bindung nicht funktioniert.

Linie Testing in XAML für das Verhalten würde ich gerne haben: Schreibtisch auf Basis dieser Stichprobe von DrawingPaint ist

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

Das Spiel: http://msdn.microsoft.com/en-us/library/aa970904.aspx (ein Bild hier)

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 und Eigenschaftsdefinition:

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(); 
     } 
    } 
} 

Antwort

11

TemplateBindings funktionieren nur für Abhängigkeitseigenschaften, die für das Steuerelement definiert sind, das templated ist (in einer ControlTemplate). Sie müssen nur diese um wechseln ein Binding mit einem RelativeSource von AncestorType zu sein (auch angebracht Eigenschaften erfordern Klammer in einer Bindung verwendet werden):

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

bearbeiten die RelativeSource Bindung aktualisiert, da es nicht war innerhalb einer ControlTemplate definiert.

+0

Ich habe diesen Fehler im Ausgabefenster von Visual Studio gefunden: System.Windows.Data Fehler: 2: Kann nicht finden, FrameworkElement oder FrameworkContentElement für Zielelement. BindingExpression: Pfad = (0); Datenelement = null; Zielelement ist 'DrawingBrush' (HashCode = 35191196); target property ist 'Viewport' (Typ 'Rect') –

+0

Entschuldigung, ich habe die von Ihnen eingestellte Immobilie nicht genau angesehen. Ich habe die Antwort so aktualisiert, dass sie tatsächlich funktioniert. –

+0

Danke, ich habe es aus Ihrem vorherigen Beispiel herausgefunden. –