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.

È stato utile?

Soluzione 2

Sono stati scoperti diversi gotcha:

  1. Sebbene possa apparire come un doppio in XAML, il valore effettivo per l'altezza o la larghezza di * Definition è una struttura "GridLength".
  2. Tutte le proprietà di GridLength sono di sola lettura, devi crearne una nuova ogni volta che la cambi.
  3. 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top