【问题标题】:Binding issue ActualWidth on dynamic filled Grid动态填充网格上的绑定问题 ActualWidth
【发布时间】:2011-11-16 05:14:38
【问题描述】:

考虑以下简单的代码:


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"/>

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

我的标签通过绑定包含第二列的ActualWidth 属性。在 Visual Studio 中,我看到我的标签包含值 316,因此绑定有效。

双击标签会触发其事件并在网格中添加一个额外的行,所有行都具有随机长度。

我希望在我的标签上看到一个新值,但是(在运行时计算的)0 没有改变!

我在这里错过了什么?

【问题讨论】:

    标签: c# wpf xaml binding actualwidth


    【解决方案1】:

    主要问题是ColumnDefinitionActualWidth 不是依赖属性,也没有实现INotifyPropertyChanged,因此Binding 无法知道coltest 的ActualWidth 已更改。

    您需要明确更新Binding

    Edit2:在这种情况下,您可以在 SizeChanged 事件中更新 Binding 以用于 Grid,因为 Columns 具有 * 宽度。这不会 100% 使用 Auto 宽度,因为宽度会根据 ColumnDefinition 中的元素而变化

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

    事件处理程序

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

    编辑:对 Xaml 做了一些小的改动。这将在您每次双击第一个 Label 时更新 Binding

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

    事件处理程序

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

    【讨论】:

    • 啊,我明白了。如何更新绑定?这取决于ActualWidth属性是什么时候计算的吧?
    • 当然可以,很高兴我能帮上忙 :)
    • 我实际上不得不听LayoutUpdated 事件。 SizeChanged 事件仅在初始化时触发。
    • 好吧,SizeChanged 事件会在每次Grid 改变大小时引发,但是如果你添加一个新的ColumnDefinition 例如,Grid 大小不会改变,但@987654346 @ 的Grid 将。 LayoutUpdated 在每次布局更新(大小更改或诸如此类)时都会引发,所以是的,不可能错过那里的更新:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    相关资源
    最近更新 更多