WPF vinculação a grade largura da coluna
Pergunta
Eu estou tentando ligar um DependancyProperty
em um dos meus usercontrols à propriedade Width
de um Column
em um Grid
.
Eu tenho código semelhante a este:
<Grid x:Name="MyGridName">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="TitleSection" Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>...</Grid.RowDefinitions>
<GridSplitter x:Name="MyGridSplitter" Grid.Row="0" Grid.Column="0" ... />
</Grid>
Em um Usercontrol separado tenho o followingDependancyProperty
definido.
public static readonly DependencyProperty TitleWidthProperty = DependencyProperty.Register("TitleWidth", typeof(int), typeof(MyUserControl));
public int TitleWidth
{
get { return (int)base.GetValue(TitleWidthProperty); }
set { base.SetValue(TitleWidthProperty, value); }
}
Estou criando instâncias do Usercontrol no código, portanto, eu tenho uma declaração de ligação semelhante a esta:
MyUserControl Cntrl = new MyUserControl(/* Construction Params */);
BindingOperations.SetBinding(Cntrl , MyUserControl.AnotherProperty, new Binding { ElementName = "objZoomSlider", Path = new PropertyPath("Value"), Mode = BindingMode.OneWay });
BindingOperations.SetBinding(Cntrl , MyUserControl.TitleWidthProperty, new Binding { ElementName = "TitleSection", Path = new PropertyPath("ActualWidth"), Mode = BindingMode.OneWay });
/* Other operations on Cntrl */
A primeira ligação de obras definidas fantasticamente, embora, que é obrigatória para um UIElement real (neste caso, um Slider), mas a ligação com "TitleSection" (que é o ColumnDefinition definido no Grid) falhar. Colocar um ponto de interrupção no código e fazer um relógio em "TitleSection" retorna o objeto esperado.
Eu estou começando a suspeitar que um x: Name'd ColumnDefinition não pode ser vinculado. alguém pode sugerir como eu poderia ser capaz de se ligar ao alterar a largura da primeira coluna na minha rede?
EDIT # 1 - Para comentários resposta ??strong>
A ligação de dados 'falha' no sentido de que com um conjunto ponto de interrupção na setter para a propriedade TitleWidth
, e usando o controle GridSplitter para redimensionar a primeira coluna, o ponto de interrupção nunca é atingido. Além disso, o código que seria de esperar para ser disparado quando as mudanças TitleWidth
DependancyProperty não ter executado.
O usercontrol está sendo criado e adicionado a uma StackPanel dentro da grade na função Window_Loaded
. Eu esperaria que a grade foi proferida pelo tempo que os Usercontrols estão sendo construídos. Certamente, o x: Name'd Elemento TitleSection
é assistível e tem um valor de 100
quando eles estão sendo construídos / antes que a ligação está acontecendo
EDIT # 2 -? Possivelmente algo a ver com este
Eu tenho tido um sniff rodada as páginas MSDN para a documentação Grade ColumnDefinition e se deparam GridLength () mas não posso colocar minha cabeça em torno de como eu posso usar isso em uma expressão de ligação. Eu não posso usar o GridLengthConverter associada como um conversor no código de ligação, uma vez que não deriva de IValueConverter.
Estou inclinado para alguma forma de ligação à propriedade ActualWidth de uma das células do objeto Grid. Não parece tão limpo como obrigatório para a definição da coluna, mas no momento eu não posso chegar a esse trabalho.
Solução
Bem, eu tenho um pouco de trabalho kludge, eu vou explicar como para as gerações futuras:
Essencialmente eu tenho a 2 coluna, grade de multi linha com um divisor alinhado à direita na primeira coluna para que possa ser redimensionada pelo usuário se o conteúdo que ele contém requer mais espaço. Para complicar as coisas Eu tenho um controle de usuário que está sendo carregado através de programação em algumas das linhas que tem um columnSpan de 2 para fins de renderização (conteúdo 'sangra' de uma célula para a próxima).
Quando a primeira coluna é redimensionada eu preciso que isso seja refletido no usercontrol. Em primeiro lugar eu tentei ligação ao ColumnDefinition mas realmente não estava jogando bola.
Como eu fixo / kludged it
Em uma célula de reposição na primeira coluna eu adicionei um <Label>
com um x: Nome para torná-lo acessível. Como é em uma célula que tem propriedades padrão de 'esticar' e preenche a célula completamente. Ele fica redimensionada como a coluna é redimensionada usando o divisor. Ligação a meios de propriedade ActualWidth
do rótulo que as mudanças no tamanho da coluna são comunicados ao DependancyProperty em meu usercontrol columnSpanned corretamente.
Pensamentos
Obviamente, apesar ColumnDefinition ter uma propriedade ActualWidth
quando ele muda ele não aparece para acionar o evento PropertyChanged
internamente (ou é o meu melhor palpite). Este pode ser um bug, ou por design, mas para mim isso significa que eu tive que usar uma solução menos limpo.
Outras dicas
Você já tentou configurar a ligação em XAML, o seguinte deve trabalhar para você.
<ColumnDefinition
x:Name="TitleSection"
Width="{Binding
Path=TitleWidth,
RelativeSource={RelativeSource AncestorType=MyUserControl}}"
/>
Caso contrário, olhar para o código de ligação que você forneceu, parece o caminho errado ao redor para me, o alvo da ligação deve ser a coluna de grade ea fonte deve ser a sua propriedade de dependência.
O código equivalente para o XAML acima é
BindingOperations.SetBinding(TitleSection, ColumnDefinition.WidthProperty,
new Binding()
{
RelativeSource= new RelativeSource(RelativeSourceMode.FindAncestor, typeof(MyUserControl),1),
Path = new PropertyPath("TitleWidth"),
});
Em uma nota relacionada, usando um GridSplitter e vinculativa a propriedade largura são mutally exclusivo. Assim que você redimensionar a coluna usando o divisor, sua ligação será substituído com o valor do divisor.
Este é semelhante ao que você iria experimentar, atualizando qualquer propriedade que é o alvo de uma ligação. Quando você define as metas de valor diretamente no código, você está substituindo esentially o objeto de ligação com o valor que você fornecer.
ColumnDefinition.Width não é um inteiro - é uma GridLength. Você não pode vincular o GridLength diretamente para o Integer, você precisa de um conversor.
Esta é também a razão, porque você não pode vincular Largura propriedade de qualquer controle (duplo) para propriedade de largura de uma ColumnDefinition (GridLength) sem um conversor.