簡體   English   中英

如何根據 WPF 中的窗口大小調整某個控件的大小?

[英]How to resize a certain control based on Window size in WPF?

我有一個ListView控件,我想在其中調整與Window大小同步的最后一列的大小。 因此,如果Window的寬度增加 100 個單位,我希望列的寬度也增加 100。

我應該在窗口上使用Resize事件並使用幻數手動調整列標題的大小,有點像?:

columnHeader.Width = windowSize.X - 400;

這是一個使用數據綁定和一些轉換器魔法來完成工作的解決方案。

首先,讓我們描述一個包含一些數據和 3 列的簡單 ListView。

<ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn Width="140" Header="Date" />
            <GridViewColumn Width="140" Header="Day" 
                            DisplayMemberBinding="{Binding DayOfWeek}" />
            <GridViewColumn Width="140" Header="Year" 
                            DisplayMemberBinding="{Binding Year}"/>
        </GridView>
    </ListView.View>

    <sys:DateTime>1/2/3</sys:DateTime>
    <sys:DateTime>4/5/6</sys:DateTime>
    <sys:DateTime>7/8/9</sys:DateTime>
</ListView>

這將使我們到達您所在的位置。 現在,為了讓最后一列根據父級寬度增長和縮小,我們需要構建一個轉換器並將其連接起來。 首先,讓我們調整 GridView 的最后一列,使寬度動態化。

<GridViewColumn Header="Year" DisplayMemberBinding="{Binding Year}">
    <GridViewColumn.Width>
        <MultiBinding Converter="{StaticResource lastColumnMaximizerConverter}">
            <Binding Path="ActualWidth" 
                     RelativeSource="{RelativeSource AncestorType=ListView}"/>
            <Binding Path="View.Columns" 
                     RelativeSource="{RelativeSource AncestorType=ListView}"/>
        </MultiBinding>
    </GridViewColumn.Width>
</GridViewColumn>

我們在這里所做的是創建了一個 MultiBinding 對象,連接了一個IMultiValueConverter ,並描述了我們想要發送到IMultiValueConverter實現的幾個參數。 第一個參數是父 ListView 的 ActualWidth。 第二個參數是父 ListView 上的 View.Columns 集合。 我們現在擁有計算視圖中最后一列的最終寬度所需的一切。

現在我們需要創建一個 IMultiValueConverter 實現。 我這里正好有一個。

public class WidthCalculationMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, 
                          object parameter, CultureInfo culture)
    {
        // do some sort of calculation
        double totalWindowWidth;
        double otherColumnsTotalWidth = 0;
        double.TryParse(values[0].ToString(), out totalWindowWidth);
        var arrayOfColumns = values[1] as IList<GridViewColumn>;

        for (int i = 0; i < arrayOfColumns.Count - 1; i++)
        {
            otherColumnsTotalWidth += arrayOfColumns[i].Width;
        }

        return (totalWindowWidth - otherColumnsTotalWidth) < 0 ? 
                     0 : (totalWindowWidth - otherColumnsTotalWidth);
    }

    public object[] ConvertBack(object value, Type[] targetTypes,
                                object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Psst..順便說一句,這不是最安全的代碼。 你會想要美化它! 這只是一個演示,你知道演示代碼是怎樣的! :)

最后,我們需要在 XAML 中實例化 Converter 實例。

<Grid.Resources>
    <Converters:WidthCalculationMultiConverter 
                  x:Key="lastColumnMaximizerConverter"/>
</Grid.Resources>

所以現在我們有一個轉換器,它會根據 ListView 中列的寬度(不包括最后一列)和一個將使用該轉換器並發送所需的綁定來確定我們想要制作的最后一列的寬度參數並得出“正確答案”並將其應用於最后一列的寬度。

如果你把它們放在一起,你現在應該有一個 ListView,其中最后一列將始終拉伸到父 ListView 的最大寬度。

我希望這能讓你繼續前進,但也幫助你了解我們如何在不編寫一些代碼隱藏和使用 WPF 提供的更多工具的情況下做到這一點。

我不能完全相信這個答案,因為我在這里得到了它

但基本上這是這個想法:

將 listView 中的“View”替換為 GridView。 然后,您可以為第一列指定所需的任何寬度。 在本例中為 100、50、50。然后我們在最后一列上添加一個綁定,它將父 ListView 控件作為輸入。 但是我們允許轉換器為我們做骯臟的工作。

<ListView>
    <ListView.View>
      <GridView>
        <GridViewColumn Header="Title" DisplayMemberBinding="{Binding}" Width="100"/>
        <GridViewColumn Header="Title" DisplayMemberBinding="{Binding}" Width="50"/>
        <GridViewColumn Header="Title" DisplayMemberBinding="{Binding}" Width="50"/>
        <GridViewColumn Header="4" DisplayMemberBinding="{Binding}">
        <GridViewColumn.Width>
          <MultiBinding Converter="{StaticResource starWidthConverter}">
            <Binding Path="ActualWidth"  RelativeSource="{RelativeSource AncestorType=ListView}"/>
            <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ListView}"/>
          </MultiBinding>
        </GridViewColumn.Width>
      </GridViewColumn>
     </GridView>
    </ListView.View>
    <ListViewItem>item1</ListViewItem>
    <ListViewItem>item2</ListViewItem>
    <ListViewItem>item3</ListViewItem>
    <ListViewItem>item4</ListViewItem>
  </ListView>

因此,在轉換器“Convert”函數中,我們執行以下操作:

ListView listview = value[1] as ListView;
double width = listview.ActualWidth;
GridView gv = listview.View as GridView;
for(int i = 0;i < gv.Columns.Count-1;i++)
{
  if(!Double.IsNaN(gv.Columns[i].Width))
    width -= gv.Columns[i].Width;
}
return width - 5;// this is to take care of margin/padding

它獲取列表視圖的寬度,並計算新的大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM