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

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.

Foi útil?

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.

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