Pergunta

De acordo com o padrão de ViewModel-ViewModel para WPF, eu estou tentando vincular as alturas e larguras de várias definições para controles de grade, para que eu possa armazenar os valores que o usuário define-los para depois de usar um GridSplitter. No entanto, o padrão normal não parece trabalho para essas propriedades particulares.

Nota: Estou postando isso como uma questão de referência que estou postando como Google falhou comigo e eu tinha que resolver isso sozinho. Minha própria resposta a seguir.

Foi útil?

Solução 2

Houve uma série de dicas que eu descobri:

  1. Embora possa parecer como um casal no XAML, o valor real para a altura de um Definition * ou largura é um struct 'GridLength'.
  2. Todas as propriedades de GridLength são somente leitura, você tem que criar um novo a cada vez que você alterá-lo.
  3. Ao contrário de todos os outros bens em WPF, largura e altura não padrão seu modo de ligação de dados para 'TwoWay', você tem que configurar manualmente este.

Thusly, eu usei o seguinte código:

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 o XAML:

<Grid.RowDefinitions>
    <RowDefinition Height="*" MinHeight="100" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="{Binding Path=HorizontalInputRegionSize,Mode=TwoWay}" MinHeight="50" />
</Grid.RowDefinitions>

Outras dicas

Criar um IValueConverter da seguinte forma:

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

Você pode então utilizar o conversor em sua Encadernação:

<UserControl.Resources>
    <local:GridLengthConverter x:Key="gridLengthConverter" />
</UserControl.Resources>
...
<ColumnDefinition Width="{Binding Path=LeftPanelWidth, 
                                  Mode=TwoWay,
                                  Converter={StaticResource gridLengthConverter}}" />

Outra possibilidade, desde que você trouxe a conversão entre GridLength e int, é criar um IValueConverter e usá-lo quando se ligar a Width. IValueConverters também lidar com duas vias de ligação, porque eles têm ambos os métodos ConvertTo() e ConvertBack().

A solução mais fácil é simplesmente usar as configurações de cordas para essas propriedades para que WPF irá apoiá-los automaticamente usando GridLengthConverter sem qualquer trabalho extra.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top