Como faço para vincular um ColumnDefinition Largura ou Altura do RowDefinition?
-
02-07-2019 - |
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.
Solução 2
Houve uma série de dicas que eu descobri:
- Embora possa parecer como um casal no XAML, o valor real para a altura de um Definition * ou largura é um struct 'GridLength'.
- Todas as propriedades de GridLength são somente leitura, você tem que criar um novo a cada vez que você alterá-lo.
- 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
. IValueConverter
s 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.