J'ai besoin d'une sorte de tableau pour les entrées de l'utilisateur. J'ai donc créé une grille avec des colonnes et des lignes définies. Le tableau n'est pas destiné à afficher des données, son but est simplement de structurer les entrées.
Pour structurer tous les éléments, comme les zones de texte, etc. J'ai défini toutes les colonnes avec une largeur. Il y aura plusieurs grilles alignées dans un stackpanel.
La définition des colonnes en XAML ressemble à ceci :
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="widthLoopID" Width="55" />
</Grid.ColumnDefinition>
Je l'ai référencé à partir d'autres grilles comme :
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=widthLoopID, Path=Width}" />
</GridColumnDefinition>
Ça marche plutôt bien.
Maintenant, la partie difficile. Comment je fais ça dans le code-behind ?
J'ai essayé ce qui suit :
// define columns
ColumnDefinition loopIdColumn = new ColumnDefinition();
// setup databinding for columns
Binding loopIdBinding = new Binding();
// set binding for width
loopIdBinding.ElementName = "widthLoopID";
loopIdBinding.Path = new PropertyPath("Width");
loopIdColumn.SetBinding(Grid.WidthProperty, loopIdBinding);
// add definition of column
loopGrid.ColumnDefinitions.Add(loopIdColumn);
Mais lorsqu'il est exécuté, j'obtiens l'erreur suivante
System.Windows.Data Error: 1 : Cannot create default converter to perform 'one-way' conversions between types 'System.Windows.GridLength' and 'System.Double'. Consider using Converter property of Binding. BindingExpression:Path=Width; DataItem='ColumnDefinition' (HashCode=37457626); target element is 'ColumnDefinition' (HashCode=7871588); target property is 'Width' (type 'Double')
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='55' BindingExpression:Path=Width; DataItem='ColumnDefinition' (HashCode=37457626); target element is 'ColumnDefinition' (HashCode=7871588); target property is 'Width' (type 'Double')
Je dois donc convertir "Width", mais comment le faire et pourquoi cela ne peut pas être effectué par le convertisseur par défaut comme dans XAML ?
Je suis assez novice en matière de WPF et il se peut que je n'aie pas compris tous les concepts, alors donnez-moi un indice.
Merci d'avance Benny
EDITAR:
J'ai essayé l'astuce de la première réponse. Cela ne fonctionne pas, car GridLengthConverter n'est pas du type IValueConverter.
J'ai donc écrit un DoubleToGridLengthConverter, qui convertit un GridLength en un Double et vice versa.
Maintenant la valeur est convertie mais le résultat n'est pas le même que celui que le code fait dans XAML. J'ai l'impression que cela ne fonctionne pas du tout à partir du code. Vraiment étrange.
Voici le code du convertisseur :
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Globalization;
using System.Diagnostics;
namespace editor
{
[ValueConversion(typeof(Double), typeof(GridLength))]
class DoubleToGridLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// check whether a value is given
if (value != null)
{
Debug.WriteLine("value is: " + value + " type: " + value.GetType());
return (Double)((GridLength)(value)).Value;
}
else
{
throw new ValueUnavailableException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// check whether a value is given
if (value != null)
{
return new GridLength((Double)value);
}
else
{
throw new ValueUnavailableException();
}
}
}
}
D'autres conseils ? Je peux imaginer que quelqu'un d'autre a déjà eu ce problème.
Merci encore Benny