c# wpf xaml binding actualwidth

c# - Problema de enlace ActualWidth en Grid lleno dinámico



wpf xaml (1)

Considere el siguiente código simple:

XAML:

<Grid Height="60" Name="grid"> <Grid.ColumnDefinitions> <ColumnDefinition Width="162*" /> <ColumnDefinition x:Name="coltest" Width="316*" /> <ColumnDefinition Width="239*" /> </Grid.ColumnDefinitions> </Grid> <Label MouseDoubleClick="TextBox_MouseDoubleClick" Content="{Binding ElementName=coltest, Path=ActualWidth}" Grid.Row="1"/>

El evento MouseDoubleClick :

private void TextBox_MouseDoubleClick(object sender, MouseButtonEventArgs e) { grid.RowDefinitions.Add(new RowDefinition()); for (int i = 0; i < grid.ColumnDefinitions.Count; i++) { Random r = new Random(); Label l = new Label { Content = r.Next(10, 1000000000).ToString() }; grid.Children.Add(l); Grid.SetRow(l, grid.RowDefinitions.Count - 1); Grid.SetColumn(l, i); } }

Mi etiqueta contiene la propiedad ActualWidth de la segunda columna a través de un enlace. En Visual Studio, veo mi etiqueta que contiene el valor 316, por lo que el enlace funciona.

Al hacer doble clic en la etiqueta se desencadena su evento y se agrega una fila adicional a la cuadrícula, todas con una longitud aleatoria.

Espero ver un nuevo valor en mi etiqueta, pero (el tiempo de ejecución calculado) 0 no cambia!

¿Que me estoy perdiendo aqui?


El principal problema es que ActualWidth de una ColumnDefinition no es una Propiedad de Dependencia, ni implementa INotifyPropertyChanged por lo que la Binding no tiene forma de saber que el ActualWidth de coltest ha cambiado.

Necesitarás actualizar explícitamente el Binding

Edit2: en este caso, es posible que pueda actualizar la Binding en el evento SizeChanged para la Grid ya que las Columns tienen * ancho. Sin embargo, esto no funcionará al 100% con ancho Auto ya que el ancho cambiará en función de los elementos en la ColumnDefinition

<Grid Name="grid" SizeChanged="grid_SizeChanged"> <!--...--> </Grid>

Controlador de eventos

void grid_SizeChanged(object sender, SizeChangedEventArgs e) { BindingExpression be = label.GetBindingExpression(Label.ContentProperty); be.UpdateTarget(); }

Editar: hizo algunos pequeños cambios en el Xaml. Esto actualizará el Enlace cada vez que haga doble clic en la primera Label

<Grid Name="grid"> <Grid.ColumnDefinitions> <ColumnDefinition Width="162*" /> <ColumnDefinition x:Name="coltest" Width="316*" /> <ColumnDefinition Width="239*" /> <ColumnDefinition Width="239*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label MouseDoubleClick="TextBox_MouseDoubleClick" Name="label" Content="{Binding ElementName=coltest, Path=ActualWidth}" Grid.Row="0"/> </Grid>

Controlador de eventos

private void TextBox_MouseDoubleClick(object sender, MouseButtonEventArgs e) { grid.RowDefinitions.Add(new RowDefinition()); for (int i = 0; i < grid.ColumnDefinitions.Count; i++) { Random r = new Random(); Label l = new Label { Content = r.Next(10, 1000000000).ToString() }; grid.Children.Add(l); Grid.SetRow(l, grid.RowDefinitions.Count - 1); Grid.SetColumn(l, i); } BindingExpression be = label.GetBindingExpression(Label.ContentProperty); be.UpdateTarget(); }