Come posso associare una larghezza di definizione di colonna o l'altezza di definizione di colonna?
-
02-07-2019 - |
Domanda
Sotto il modello View-Model-ViewModel per WPF, sto cercando di associare le altezze e le larghezze delle varie definizioni per i controlli della griglia, in modo da poter memorizzare i valori su cui l'utente li imposta dopo aver usato un GridSplitter. Tuttavia, il modello normale non sembra funzionare per queste proprietà particolari.
Nota: sto pubblicando questo come una domanda di riferimento che sto pubblicando perché Google mi ha fallito e ho dovuto risolverlo da solo. La mia risposta da seguire.
Soluzione 2
Sono stati scoperti diversi gotcha:
- Sebbene possa apparire come un doppio in XAML, il valore effettivo per l'altezza o la larghezza di * Definition è una struttura "GridLength".
- Tutte le proprietà di GridLength sono di sola lettura, devi crearne una nuova ogni volta che la cambi.
- A differenza di qualsiasi altra proprietà in WPF, Larghezza e Altezza non impostano la modalità di database su "TwoWay", è necessario impostarla manualmente.
Pertanto, ho usato il seguente codice:
private GridLength myHorizontalInputRegionSize = new GridLength(0, GridUnitType.Auto)
public GridLength HorizontalInputRegionSize
{
get
{
// If not yet set, get the starting value from the DataModel
if (myHorizontalInputRegionSize.IsAuto)
myHorizontalInputRegionSize = new GridLength(ConnectionTabDefaultUIOptions.HorizontalInputRegionSize, GridUnitType.Pixel);
return myHorizontalInputRegionSize;
}
set
{
myHorizontalInputRegionSize = value;
if (ConnectionTabDefaultUIOptions.HorizontalInputRegionSize != myHorizontalInputRegionSize.Value)
{
// Set the value in the DataModel
ConnectionTabDefaultUIOptions.HorizontalInputRegionSize = value.Value;
}
OnPropertyChanged("HorizontalInputRegionSize");
}
}
E XAML:
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="100" />
<RowDefinition Height="Auto" />
<RowDefinition Height="{Binding Path=HorizontalInputRegionSize,Mode=TwoWay}" MinHeight="50" />
</Grid.RowDefinitions>
Altri suggerimenti
Crea un IValueConverter
come segue:
public class GridLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double val = (double)value;
GridLength gridLength = new GridLength(val);
return gridLength;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
GridLength val = (GridLength)value;
return val.Value;
}
}
Puoi quindi utilizzare il convertitore nel tuo Binding:
<UserControl.Resources>
<local:GridLengthConverter x:Key="gridLengthConverter" />
</UserControl.Resources>
...
<ColumnDefinition Width="{Binding Path=LeftPanelWidth,
Mode=TwoWay,
Converter={StaticResource gridLengthConverter}}" />
Un'altra possibilità, dal momento che hai avviato la conversione tra GridLength
e int
, è quella di creare un IValueConverter
e utilizzarlo quando si associa a Larghezza
. Anche i IValueConverter
gestiscono l'associazione bidirezionale perché hanno entrambi i metodi ConvertTo ()
e ConvertBack ()
.
La soluzione più semplice è semplicemente utilizzare le impostazioni di stringa per queste proprietà in modo che WPF le supporti automaticamente utilizzando GridLengthConverter senza alcun lavoro aggiuntivo.