2011-04-06 77 views
2

我有一個ListView控件,我想調整最後一列的大小,使其與Window的大小同步。因此,如果Window的寬度增加100個單位,我希望列的寬度也增加100.如何根據WPF中的窗口大小調整某個控件的大小?

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

columnHeader.Width = windowSize.X - 400; 

回答

1

我不能充分信貸這個答案,因爲我得到了它here

但基本上是這樣的想法:

更換「查看」與GridView的ListView控件。然後,您可以爲第一列指定任何想要的寬度。在這種情況下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> 

所以,在轉換器 '轉換' 功能,我們這樣做:

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 

哪個抓住ListView的寬度,並計算新的大小。

+0

順便說一句我忘了問,但是當以編程方式設置列寬時,是否會像用戶在手動調整對應單元格的大小時那樣調整大小? – 2011-04-07 00:03:05

+0

好吧,我添加了這個,但它沒有做任何事情,寬度看起來像它被設置爲自動,但我添加了轉換器和綁定,視圖已經設置爲gridviewcolumn像在Dave的帖子。 – 2011-04-07 00:20:36

+0

對不起,我做了一個糟糕的假設,我提供的鏈接中的代碼實際上工作。現在它應該工作。 – Liz 2011-04-07 00:29:16

7

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

首先,讓我們描述一個簡單的帶有一些數據和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> 

所以現在我們有AA轉換器,它會找出我們想要多寬,使最後一列的基礎上,列在ListView的寬度(不包括最後一個)和綁定將使用該轉換器併發送所需參數並獲得「正確答案」並將其應用到最後一列的寬度。

如果你把這個共同的權利,你現在應該有一個ListView中的最後一列會一直延伸到父ListView中的最大寬度。

我希望這可以讓你去,但也幫助你理解我們如何做到這一點,而無需編寫一些代碼隱藏和使用WPF提供的更多設施。

+0

順便說一句我忘了問,但是當以編程方式設置列寬時,它是否會像用戶在相應的單元格被調整大小時手動調整它的大小? – 2011-04-07 00:02:45

+0

我不知道我是否理解您的問題,但是如果您調整列的大小,那麼該列中的所有單元格將與列寬相匹配。您不必調整所有單元格的大小。 – 2011-04-07 05:52:30

+0

謝謝,這正是我所問的。我問這個問題的原因是因爲當你隱藏一個columnheader時,它並沒有隱藏單元格,所以我認爲縮放也適用於columnheader。 – 2011-04-07 16:37:21

相關問題