我当前正在尝试查找/实现WPF控件,该控件是Grid
和StackPanel
的组合。就是说,我喜欢两列包含几个项目。一个项目是另一个控件(例如,单个Label
,TextBox
在面板中带有标签,...)。
如果一个项目被折叠,则下一个项目应填充空白区域,这意味着我在控件中使用的空间总是尽可能地少(单个项目之间没有间隙)。
我附加了两个图像,看起来应该是这样。
初始:
Item4已折叠(注意后续项目的转移):
有人有想法或经验如何做这样的事情吗?
答案 0 :(得分:0)
您可以使用将StackPanel或DockPanel用作ItemTemplate的ListView。 这是我用来在Grid和DockPannel列表中显示可观察对象集合的示例(简化):
<ListView x:Name="lbxDroppedDatas" SelectionMode="Single" AllowDrop="True" BorderThickness="0" Padding="0" Margin="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="lbxDroppedDatas_SelectionChanged" PreviewKeyDown="lbxDroppedDatas_PreviewKeyDown" PreviewMouseRightButtonDown="lbxDroppedDatas_PreviewMouseRightButtonDown" >
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel Grid.Row="0" Width="{Binding Path=ActualWidth, ElementName=Container}" Height="40" Margin="1" LastChildFill="True">
<CheckBox DockPanel.Dock="Left" IsChecked="{Binding IsChecked}" VerticalAlignment="Center" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
<Label Content="{Binding Name}" Foreground="{Binding LineBrush}" FontWeight="Bold" FontSize="12" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="0" MouseEnter="Label_MouseEnter" MouseLeave="Label_MouseLeave"/>
<TextBox DockPanel.Dock="Right" Width="60" MaxLength="14" Text="{Binding CurrentValue, StringFormat=N}" Margin="0,0,33,0" Background="Transparent" Foreground="{Binding LineBrush}" BorderBrush="{Binding LineBrush}" BorderThickness="1" VerticalAlignment="Center" HorizontalAlignment="Right" IsEnabled="False"/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" VerticalAlignment="Stretch" Margin="0"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
您可以将列表元素的可见性绑定到折叠或可见的属性。
答案 1 :(得分:0)
我将通过以下方式解决此问题:
首先创建具有两个堆栈面板的网格(该网格位于UserControl或任何其他占位符内):
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel x:Name="LeftPanel" x:FieldModifier="private" Orientation="Vertical" />
<StackPanel x:Name="RightPanel" x:FieldModifier="private" Grid.Column="1" Orientation="Vertical" />
</Grid>
要控制项目,请创建项目列表,最好在UserControl的代码内:
private List<FrameworkElement> m_items = new List<FrameworkElement>();
对于不想显示的项目,将Visibility
设置为Hidden
或Collapsed
。
您需要一些方法来选择可见项并将其交替放置在左右面板上。我想出了一些快速方法,每次列表更改(添加或删除项目,项目的可见性更改)时,您都需要调用该方法:
public void SortItems()
{
this.LeftPanel.Children.RemoveRange(0, this.LeftPanel.Children.Count);
this.RightPanel.Children.RemoveRange(0, this.RightPanel.Children.Count);
this.m_items.Where(i => i.Visibility == Visibility.Visible).ToList().ForEach((i) => { (this.LeftPanel.Children.Count == this.RightPanel.Children.Count ? this.LeftPanel : this.RightPanel).Children.Add(i); } );
}
该方法仅删除堆叠面板的所有子代,然后遍历项目列表,仅选择Visible
的那些子代,如果两个面板中都有相同数量的项目,则在左侧面板中添加一个;否则,请转到右侧面板。
如果您需要其他选择面板的方法,则应添加以下项目(例如ActualHeight
),只需更改选择面板的条件即可。
如果要使此方法更优雅,可以添加一些事件或依赖项属性,这些事件或依赖项属性将自动调用SortItems
。无论如何,这是一个好的开始。
答案 2 :(得分:0)
非常感谢您提供所有不同的解决方案。最后,我用Sinatr的建议解决了它。因此,我创建了自己的面板并覆盖ArrangeOverride:
protected override Size ArrangeOverride(Size finalSize)
{
List<UIElement> visibleItems = new List<UIElement>();
double xColumn1 = 0;
double xColumn2 = (finalSize.Width / 2) + (WIDTH_COLUMN_SEPERATOR / 2);
double y = 0;
double columnWidth = (finalSize.Width - WIDTH_COLUMN_SEPERATOR) / 2;
for (int i = 0; i < InternalChildren.Count; i++)
{
UIElement child = InternalChildren[i];
if (child.Visibility != Visibility.Collapsed)
{
visibleItems.Add(child);
}
}
for (int i = 0; i < visibleItems.Count; i++)
{
if (i >= (visibleItems.Count - 1))
{
visibleItems[i].Arrange(new Rect(xColumn1, y, columnWidth, visibleItems[i].DesiredSize.Height));
}
else
{
UIElement leftItem = visibleItems[i];
UIElement rightItem = visibleItems[i + 1];
double rowHeight = leftItem.DesiredSize.Height > rightItem.DesiredSize.Height ? leftItem.DesiredSize.Height : rightItem.DesiredSize.Height;
leftItem.Arrange(new Rect(xColumn1, y, columnWidth, rowHeight));
rightItem.Arrange(new Rect(xColumn2, y, columnWidth, rowHeight));
y += rowHeight;
i++;
}
}
return finalSize;
}
我还为商品创建了自己的UserControl:
<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="captionLabel" Grid.Row="0" Content="{Binding Caption}"/>
<ContentPresenter x:Name="inputMask" Grid.Row="1" Content="{Binding InputMask, ElementName=userControlBRAIN2AttributePanelItem}" />
</Grid>
所以我得到以下结果(从我的测试应用程序中得到):
项目3折叠:
答案 3 :(得分:0)
令我惊讶的是,没有人建议使用UniformGrid
。
您要做的就是声明UniformGrid
,将Columns
设置为2并添加您的项目。折叠的项目应将其Visibility
设置为Collapsed
(duh)。
这是一个例子:
<UniformGrid Columns="2"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock Text="Item 1 " />
<TextBlock Text="Item 2 " />
<TextBlock Text="Item 3 " />
<TextBlock Text="Item 4 " />
</UniformGrid>
将产生以下结果:
当第二个Visibility
的{{1}}设置为TextBlock
时,如下所示: