WPF将控件宽度绑定到ListBox列宽

时间:2011-07-20 21:57:12

标签: c# wpf binding

我按如下方式编写了XAML:

<UserControl.Resources>

    <GridViewColumnCollection x:Key="gvcc">
        <GridViewColumn Header="Klient"
                  DisplayMemberBinding="{Binding CustomerName}"
                  Width="80">
        </GridViewColumn>
        <GridViewColumn Header="Budżet"
                  DisplayMemberBinding="{Binding Budget, StringFormat={}{0:C}}"
                  Width="80">
        </GridViewColumn>
        <GridViewColumn Header="Zysk. zakł."
                  DisplayMemberBinding="{Binding ExpectedProfability, StringFormat={}{0:C}}"
                  Width="80">
        </GridViewColumn>
        <GridViewColumn Header="Zysk. real."
                  DisplayMemberBinding="{Binding RealProfability, StringFormat={}{0:C}}"
                  Width="80">
        </GridViewColumn>
        <GridViewColumn Header="Miejsce"
                  DisplayMemberBinding="{Binding Place}"
                  Width="80" />
        <GridViewColumn Header="Nr proj."
                  DisplayMemberBinding="{Binding Number}"
                  Width="80">
        </GridViewColumn>

    </GridViewColumnCollection>

</UserControl.Resources>

...

<Grid>
        <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Visible">
            <ItemsControl ItemsSource="{Binding GroupedProjects}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="70" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Red" >
                                <TextBlock FontSize="13" Text="{Binding Month}" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" />
                            </Border>

                            <GridViewHeaderRowPresenter Name="hrp" Columns="{StaticResource gvcc}" Grid.Column="1" Grid.Row="0" />
                            <ListBox ItemsSource="{Binding Details}" Grid.Column="1" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Disabled"
                                     GotFocus="ListBox_GotFocus"
                                     PreviewMouseWheel="ListBox_PreviewMouseWheel"
                                     SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.SelectedProject}">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <GridViewRowPresenter Columns="{StaticResource gvcc}" Height="24" />
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
<!-- HERE IS THE PROBLEM -->
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>
    </Grid>

数据在ListBox中分组,在ListBox下面我想显示类似摘要行的内容。我希望将此行作为带有TextBlock控件的StackPanel。问题是 - 如何将TextBox控件的宽度与ListBox中列的宽度相关联。

让我们说“摘要行”是这样的:

<StackPanel Orientation="Horizontal">
<TextBlock Width="bind to ListBox.Column1.Width + ListBox.Column2.Width">some data</TextBlock>
<TextBlock Width="bind to ListBox.Column3.Width">other data</TextBlock>
<TextBlock Width="bind to ListBox.Column4.Width">etc.</TextBlock>
</StackPanel>

如您所见 - 第一个TextBlock宽度类似于“ColumnSpan = 2”。其他TextBlocks的宽度就是我想要将它们配对的列的宽度。

在XAML中甚至可以做到这样的事情吗?你们中的任何人都知道如何以不同的方式实现类似的解决方案吗?

1 个答案:

答案 0 :(得分:1)

如果您是通过MVVM执行此操作,则可以轻松使用属性绑定来完成此操作。只需将每个ListBox列的宽度设置为ViewModel中的属性即可。 textBox控件的宽度将绑定到一个单独的readonly属性,该属性采用适当的宽度,以某种方式操作它们,并返回一个值。每次更改listboxwidth属性时,您都必须实现INotifyPropertyChanged并在每个文本框宽度属性上调用它。

所以这样:

Private _Column1Width As Double
Public Property Column1Width() As Double
    Get
        Return _Column1Width
    End Get
    Set(ByVal value As Double)
        _Column1Width = value
        OnPropertyChanged("TextBox1Width")
    End Set
End Property

Private _Column2Width As Double
Public Property Column2Width() As Double
    Get
        Return _Column2Width
    End Get
    Set(ByVal value As Double)
        _Column2Width = value
        OnPropertyChanged("TextBox1Width")
    End Set
End Property

Public ReadOnly Property TextBox1Width() As Double
    Get
        Return Column1Width + (Column2Width * 2)
    End Get
End Property

和像这样的绑定:

    <GridViewColumnCollection x:Key="gvcc">
        <GridViewColumn Header="Klient"
                  DisplayMemberBinding="{Binding CustomerName}"
                  Width="{Binding Column1Width, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"}">
        </GridViewColumn>
        <GridViewColumn Header="Budżet"
                  DisplayMemberBinding="{Binding Budget, StringFormat={}{0:C}}"
                  Width="{Binding Column2Width, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        </GridViewColumn>
        <GridViewColumn Header="Zysk. zakł."
                  DisplayMemberBinding="{Binding ExpectedProfability, StringFormat={}{0:C}}"
                  Width="80">
        </GridViewColumn>
        <GridViewColumn Header="Zysk. real."
                  DisplayMemberBinding="{Binding RealProfability, StringFormat={}{0:C}}"
                  Width="80">
        </GridViewColumn>
        <GridViewColumn Header="Miejsce"
                  DisplayMemberBinding="{Binding Place}"
                  Width="80" />
        <GridViewColumn Header="Nr proj."
                  DisplayMemberBinding="{Binding Number}"
                  Width="80">
        </GridViewColumn>
    </GridViewColumnCollection>

<TextBlock Width="{Binding TextBox1Width}">some data</TextBlock>

在调整列大小时,所有内容都会调整,因为它应该不断更新。