Tôi có một WrapPanel, Và tôi muốn chỉ định số cột tối đa của cột. Vì vậy, ví dụ, khi Bộ sưu tập của tôi "ObjectCollection" (liên kết với WrapPanel này) chỉ chứa 4 phần tử, WrapPanel sẽ chỉ có một hàng. Nhưng, khi "ObjectCollection" sẽ có 5 phần tử, wrapPanel sẽ tạo một hàng khác để đặt hàng thứ 5. (Max_Columns_Number của tôi trong trường hợp này là 4).Chỉ định số cột tối đa cho một WrapPanel trong WPF
Trả lời
Tôi chắc rằng bạn không thể làm điều đó với số WrapPanel, nhưng bạn có thể sử dụng số UniformGrid để thay thế.
Điều đó có thuộc tính để chỉ định số hàng và cột bạn muốn.
Nếu bạn đặt thuộc tính Columns
thành 4, nó sẽ giữ 4 mục trong mỗi hàng và sau đó bao gồm các mục tiếp theo.
<UniformGrid Columns="4">
<!-- In first row -->
<Button Content="test"></Button>
<Button Content="test"></Button>
<Button Content="test"></Button>
<Button Content="test"></Button>
<!-- In second row -->
<Button Content="test"></Button>
</UniformGrid>
Có! đó là những gì tôi đã làm, và nó hoạt động – NTinkicht
Về cơ bản bạn sẽ cần phải tạo ra một phong tục Panel
cho chính mình ... bây giờ không nhận được chán nản ... nó không phải rằng khó khăn. Để bắt đầu, xin vui lòng hãy xem các bài viết mà tôi đã cung cấp các liên kết cho điều đó giải thích làm thế nào để tạo ra một tùy chỉnh Panel
:
How to create a Custom Layout Panel in WPF
Ok, vì vậy bây giờ bạn biết thêm một chút về việc tạo tùy chỉnh Panel
s, chúng ta có thể tiếp tục ... đây là những gì bạn sẽ cần:
private int columnCount;
private double leftColumnEdge, rightColumnEdge, columnWidth;
public int ColumnCount
{
get { return columnCount; }
set
{
if (value < 1) value = 1;
columnCount = value;
}
}
tài sản này sẽ được sử dụng khi bạn khai báocủa bạn 0 trong Resources
:
<ItemsPanelTemplate x:Key="AnimatedPanel">
<Controls:AnimatedColumnWrapPanel ColumnCount="3" ... />
</ItemsPanelTemplate>
Lưu ý rằng bạn sẽ cần phải khai báo nó bên một đối tượng ItemsPanelTemplate
bởi vì đó là những gì các ItemsPanel
bất động sản kỳ vọng:
<ListBox ItemsPanel="{StaticResource AnimatedPanel}" ... />
Bây giờ trở lại Panel
... đây là phương thức trợ giúp mà tôi gọi từ các phương pháp MeasureOverride
và ArrangeOverride
:
private void UpdateColumns(int currentColumn, Size finalSize)
{
leftColumnEdge = (finalSize.Width/ColumnCount) * currentColumn;
rightColumnEdge = (finalSize.Width/ColumnCount) * (currentColumn + 1);
columnWidth = rightColumnEdge - leftColumnEdge;
}
Thật không may cho bạn, tôi không thể cung cấp cho bạn một ví dụ hoàn chỉnh vì tùy chỉnh của tôi Panel
s tất cả được gắn vào lớp cơ sở AnimatedPanel
với nhiều chức năng bổ sung. Tuy nhiên, bạn chỉ cần tạo các phương thức MeasureOverride
và ArrangeOverride
để hoàn tất việc này Panel
. Nếu bạn chỉ nghĩ một cách hợp lý về nó, nó là thực sự không phải là khó khăn.
Vâng đây là cấp độ chuyên nghiệp. Điều này là nhiều hơn như cho bạn hay tôi :) Anh ta dường như không hiểu cách bố trí. Anh ta sẽ tốt hơn với Grid hoặc UniformGrid. –
Tôi hoàn toàn chấp nhận điều đó, nhưng hy vọng * một số * người dùng sẽ thấy trang này hữu ích theo thời gian. – Sheridan
Chắc chắn rất nhiều thứ đang diễn ra ở đó. đo quá trình khoan, tính toán, sắp xếp. Nhưng nó lên đến người dùng để quyết định có nên bắt đầu từ đầu hay không. –
Bạn có thể kiểm soát số cột bằng cách đặt chiều rộng của bảng điều khiển bao bọc. Tôi liên kết chiều rộng của bảng điều khiển bọc với ActualWidth của một vùng chứa như Border. Bằng cách đó, số cột là động và được dựa trên chiều rộng của cửa sổ.
<Border Name="DataBorder" Grid.Row="0" Grid.Column="1"
BorderBrush="Navy" BorderThickness="1,2,2,2"
Padding="4">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel>
<TextBlock Text="{Binding NewPictureCountDisplay}"></TextBlock>
</StackPanel>
<ListBox Name="NewFilesListBox" Grid.Row="1"
ItemsSource="{Binding CreatedFiles}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Width="{Binding ElementName=DataBorder, Path=ActualWidth}"></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="{Binding FullPath}" Width="128" Height="128" Stretch="UniformToFill"></Image>
<StackPanel Grid.Row="1" Orientation="Vertical">
<Button Content="Import" Margin="2"></Button>
<Button Content="Delete" Margin="2"></Button>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding FullPath}" Margin="2"></TextBlock>
<TextBlock HorizontalAlignment="Stretch" Text="{Binding ChangeType}" Margin="2"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Đôi khi UniformGrid là không đủ:
- khi mặt hàng có kích thước rất khác nhau, hoặc
- khi bạn muốn mục theo chiều dọc và không muốn sử dụng other workarounds
Trong this stackoverflow post có thể được tìm thấy WrapPanel với những gì bạn đang tìm kiếm.
XAML:
<loc:WrapPanelWithRowsOrColumnsCount
xmlns:loc="clr-namespace:..."
Orientation="Vertical"
RowsOrColumnsCount="2">
<TextBox Text="Andrew" Margin="2" Height="30" />
<TextBox Text="Betty" Margin="2" Height="40" />
<TextBox Text="Celine" Margin="2" Height="20" />
<TextBox Text="Dick" Margin="2" Height="20" />
<TextBox Text="Enron" Margin="2" Height="30" />
<TextBox Text="Felix" Margin="2" Height="20" />
<TextBox Text="Hanibal" Margin="2" Height="30" />
</loc:WrapPanelWithRowsOrColumnsCount>
Kết quả:
bạn không thực sự cần phải viết bảng điều khiển tùy chỉnh của bạn cho việc này chỉ cần sử dụng một mạng lưới thay vì wrappanel như ItemsPanel của bạn trong listbox . mặc dù bạn sẽ phải thông báo cho mỗi listboxitem về hàng hoặc cột lưới mà nó thuộc về –