簡體   English   中英

拉伸控件以填充ItemsControl

[英]Stretching controls to fill ItemsControl

我正在嘗試編寫一個簡單的WPF學習項目,該項目在可調整大小的主窗口內創建一組按鈕。 集合中的每個條目都有一個Button ,並且該集合的內容在運行時可能會有所不同。 我希望按鈕能夠填滿整個窗口(例如1個按鈕@ 100%寬度,2個按鈕@ 50%寬度,3個按鈕@ 33%寬度等等都在100%高度)。 我到目前為止所編寫的簡化版本是:

<ItemsControl x:Name="itemscontrolButtons" ItemsSource="{Binding}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Button Tag="{Binding}">
        <TextBlock Text="{Binding}" />
      </Button>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
</ItemsControl>
...    
List<string> listButtonTexts = new List<string>() { "Button1", "Button2" };
...
itemscontrolButtons.DataContext = listButtonTexts;

這導致:

替代文字

我無法使按鈕拉伸以適應寬度,我嘗試使用Grid而不是StackPanel是徒勞的。

然后,作為一個可選的改進,我將很感激如何調整它的建議,如果有這么多的按鈕,他們不能正確地適合在一條線上或比一個閾值窄,它將包裹到一個新的線(從而減半按鈕高度,如果從1到2行)。

我想強調一下,我想知道如何以WPF的方式做到這一點 我意識到我可以使用窗口調整大小的消息並顯式調整控件的大小,這就是我用MFC或WinForms完成它的方式,但從我讀過的內容並不是如何用WPF完成的。

將項目控件的面板替換為UniformGrid,這將調整所有子項的大小,以便所有內容完全適合:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

我能夠建立在Nir的答案上,以實現我的可選標准,允許WPF管理的多行拉伸。

首先,您必須能夠更改模板UniformGrid的屬性。 為此,您需要存儲對它的引用。 多種方法可以實現這一點 我選擇處理UniformGridLoaded事件並在那時存儲引用。

<ItemsControl ItemsSource="{Binding}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <UniformGrid Rows="1" Loaded="UniformGrid_Loaded" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
</ItemsControl>

並在代碼背后:

UniformGrid uniformgridButtons;
private void UniformGrid_Loaded(object sender, RoutedEventArgs e)
{
  uniformgridButtons = sender as UniformGrid;
}

然后,處理SizeChanged事件並根據您希望的任何條件調整rows參數。

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
  if ((uniformgridButtons != null) && (this.Width > 0))
  {
    // Set row count according to your requirements
    uniformgridButtons.Rows = (int)(1 + ((this.MinWidth * iButtonCount) / this.Width));
  }
}

因此,這允許WPF像Nir的答案一樣管理拉伸,但允許您明確調整行數。 上面的代碼給出了這個結果:

替代文字

這里的動畫樣本)


更新2009/08/28:

我正在調整我的學習應用程序,以便ItemsControl在一個單獨的ResourceDictionary中的DataTemplate中。 但是,諸如Loaded事件無法在外部ResourceDictionary XAML文件中處理,因為它沒有代碼隱藏(通常)。 因此,我需要使用不同的技術緩存對UniformGrid的引用。

我使用了Alan Haigh的FindItemsPanel方法(第10個回復) 首先,我將ItemsControl替換為:

<ContentPresenter x:Name="contentpresenterButtons" Content="{Binding obscolButtons}" />

然后在我的ResourceDictionary ,我將ItemsControl放在DataTemplate

<DataTemplate DataType="{x:Type local:Buttons}">
  <ItemsControl ... 
</DataTemplate>

最后,我將引用存儲到模板化的UniformGrid如下所示:

private void Window_Loaded(object sender, RoutedEventArgs e) {
  uniformgridButtons = FindItemsPanel<UniformGrid>(contentpresenterButtons);
  // Also call the code in Window_SizeChanged which I put in another method
}

這與我之前的解決方案一樣,但不需要ResourceDictionary的事件處理程序。

<!-- width must be explicitly set for this example -->
<StackPanel 
    Name="MyStack" 
    Orientation="Horizontal"
    Width="250"
    Load="Window_Loaded"> 
    <Button/>
    <Button/>
    <Button/>
</StackPanel>

public void Window_Loaded(object sender, RoutedEventArgs e)
{
    UIElementCollection elements = MyStack.Children;
    int count = elements.Count;

    foreach (UIElement element in elements)
    {
        if (element is Button)
            ((Button)element).Width = MyStack.Width / count;
    }
}

暫無
暫無

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

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