Travailler sur une zone de liste déroulante qui affiche une liste des arrière-plans de tuiles disponibles. Ceci est juste un ComboBox simple avec un ensemble ItemSource à une collection d'objets MapTileBackground.La liaison WPF dans le modèle de données ne fonctionne pas pour la classe personnalisée
La classe MapTileBackground est définie entièrement avec des propriétés:
public partial class MapTileBackground
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public byte[] Content { get; set; }
public Nullable<int> Color { get; set; }
public int StrokeColor { get; set; }
public byte StrokeThickness { get; set; }
}
qui est défini dans une bibliothèque séparée et je préférerais changer pas.
I ont défini une simple extension de forme pour dessiner le fond ::
public class MapTileBackgroundPreview : Shape
{
public static readonly DependencyProperty SizeProperty = DependencyProperty.Register("Size", typeof(Point), typeof(MapTileBackgroundPreview));
public static readonly DependencyProperty TileBackgroundProperty = DependencyProperty.Register("TileBackground", typeof(MapTileBackground), typeof(MapTileBackgroundPreview));
public MapTileBackgroundPreview()
{
layout = new Hex.Layout(Hex.Orientation.Flat, new Hex.Point(8, 8), new Hex.Point(4, 4));
Size = new Point(8, 8);
TileBackground = null;
}
private Hex.Layout layout;
protected override Geometry DefiningGeometry
{
get
{
var points = layout.HexCorners(0, 0).ToArray();
var path = new PathFigure();
path.StartPoint = points[5].ToWin();
for (var i = 0; i < 6; i++)
path.Segments.Add(new LineSegment(points[i].ToWin(), true));
var geo = new PathGeometry();
geo.Figures.Add(path);
return geo;
}
}
public Point Size
{
get
{
return (Point)GetValue(SizeProperty);
}
set
{
SetValue(SizeProperty, value);
layout.Size = value.ToHex();
layout.Origin = new Hex.Point(layout.Size.X/2, layout.Size.Y/2);
}
}
public MapTileBackground TileBackground
{
get
{
return (MapTileBackground)GetValue(TileBackgroundProperty);
}
set
{
SetValue(TileBackgroundProperty, value);
if (value == null)
{
Fill = Brushes.Transparent;
Stroke = Brushes.Black;
StrokeThickness = 1;
}
else
{
Stroke = value.Stroke();
StrokeThickness = value.StrokeThickness();
Fill = value.Fill(layout.Orientation);
}
}
}
}
La disposition est tout simplement un utilitaire de conversion entre les coordonnées de pixels de l'écran et d'un système hexagonal. DefiningGeometry ajoute simplement 6 segments de ligne de l'hexagone. Le setter TileBackground, lorsqu'il reçoit un MapTileBackground non nul, met à jour le contour et le remplissage comme définit l'arrière-plan. J'ai testé ce contrôle avec succès (en dehors du modèle de données de la zone de liste déroulante).
Et en parlant de:
<DataTemplate x:Key="TileListItemRenderer">
<Grid Width="225">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="75"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:MapTileBackgroundPreview Grid.Row="0" Grid.Column="0" Size="12,12" VerticalAlignment="Center" HorizontalAlignment="Center" TileBackground="{Binding /}"/>
<Label Grid.Row="0" Grid.Column="1" Content="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center" FontWeight="Bold"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Description}" HorizontalAlignment="Stretch" VerticalAlignment="Top" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
Je viens donc de créer une forme, et deux étiquettes, lier la forme à l'objet MapTileBackground actuelle (zone de liste déroulante ItemSource est une collection d'objets MapTileBackground), et les étiquettes à Nom et description.
Mon problème est que la forme est toujours dessinée vide (comme dans TileBackground est null) et le setter n'est jamais invoqué. L'étiquette de nom et le TextBlock de description se comportent comme prévu (afficher le texte correct). Et pendant mes tentatives de débogage, j'ai créé une propriété id sur l'objet de prévisualisation qui invoque à son tour le Setter TileBackground et l'a lié à la propriété Id (éviter la liaison d'objet courante), encore une fois, le setter TileBackgroundId n'est jamais invoqué. J'ai même ajouté une nouvelle étiquette liée à Id pour voir si cela fonctionnait et elle affiche l'identifiant comme prévu. Voici les changements qui n'ont pas encore fonctionné. Les propriétés TileBackgroundId ou TileBackground ne sont jamais définies lors de l'ouverture de la liste déroulante.
<DataTemplate x:Key="TileListItemRenderer">
<Grid Width="225">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="75"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:MapTileBackgroundPreview Grid.Row="0" Grid.Column="0" Size="12,12" VerticalAlignment="Center" HorizontalAlignment="Center" TileBackgroundId="{Binding Id}"/>
<Label Grid.Row="0" Grid.Column="0" Content="{Binding Id}" HorizontalAlignment="Left" VerticalAlignment="Center" FontWeight="Bold"/>
<Label Grid.Row="0" Grid.Column="1" Content="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center" FontWeight="Bold"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding Description}" HorizontalAlignment="Stretch" VerticalAlignment="Top" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
public static readonly DependencyProperty TileBackgroundIdProperty = DependencyProperty.Register("TileBackgroundId", typeof(int), typeof(MapTileBackgroundPreview));
public int TileBackgroundId
{
get
{
return (int)GetValue(TileBackgroundIdProperty);
}
set
{
SetValue(TileBackgroundIdProperty, value);
TileBackground = TMapTileBackgroundTool.Get(value);
}
}
TMapTileBackgroundTool.Get() renvoie l'objet correct en fonction de l'ID.
J'ai également testé des instances de MapTileBackgroundPreview en définissant TileBackgroundId en dehors du modèle de données.
Des idées sur ce qui se passe?
Pouvez-vous partager la 'Hex'?ou l'enlever dans le code ci-dessus? – Iron
Dans ce contexte, Hex est un alias d'espace de noms. – David