我的Silverlight应用程序中有一个带按钮的菜单屏幕。为此,我使用带有WrapPanel的ItemsControl作为ItemsPanel模板,因此按钮将换行到下一行(就像文本框中的文本一样)。
菜单是这样的:
现在我需要一个新功能:将按钮分组。所以我决定使用Accordion和ZeroOrMore项目。我使用ScrollViewer作为Accordion ContentTemplate, MaxHeight为150 将组高限制为150,然后使用垂直滚动条。在ScrollViewer中,有与WrapPanel和按钮相同的ItemsControl。
我希望WrapPanel有 3行项目而不滚动,所以我选择MaxHeight = 150是有原因的:因为每个按钮(带边距)的高度为50.这将允许3行没有滚动条。没有手风琴就行得很好,但是不能用它。
问题在于手风琴似乎并不理解WrapPanel高度,并假设它只有1行的高度,即带有边距的1个按钮的高度。因此,当我展开Accordion项目时,它的高度始终为50.如果我只有1行项目,那就没关系,但是如果我有2行或更多行,则高度不会增加到100或150,它就是'由于手风琴的高度不够,所以仍然显示50和滚动条。
以下是目前正在发生的事情:
如果我手动设置ScrollViewer或WrapPanel的宽度或高度,则问题不会发生。但它是一个可调整大小的窗口,我不知道它的大小或每个组中的数量。用户自定义,因此我无法设置高度或宽度。我需要Accordion来正确计算高度。
在这里,出于测试目的,我设置了ScrollViewer Width = 350 (比Accordion / UserControl宽度略小,所以我们可以很容易地看到它),以及MaxHeight = 100 (因此对第二组来说还不够)。
上图显示了我想要的内容,但没有宽度,因此用户可以调整窗口大小并在屏幕上显示更多按钮。
当我展开手风琴时,我注意到WrapPanel动态调整按钮,因为我可以看到它发生,我可以看到从第一行末尾到下一行的物品。所以我假设,在扩展手风琴之前,WrapPanel没有宽度(可能是它的无穷大),这就是它还没有包裹按钮的原因。它"认为"第一行中的所有项目都有空间。
以下是我写的用于显示问题的Silverlight应用程序。 MainPage.xaml :
<ScrollViewer Padding="0" BorderThickness="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="5">
<Grid>
<toolkit:Accordion HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="10"
HorizontalContentAlignment="Left" VerticalContentAlignment="Stretch"
ItemsSource="{Binding Groups}" SelectionMode="ZeroOrMore">
<toolkit:Accordion.ItemContainerStyle>
<Style TargetType="toolkit:AccordionItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</toolkit:Accordion.ItemContainerStyle>
<toolkit:Accordion.AccordionButtonStyle>
<Style TargetType="toolkit:AccordionButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:AccordionButton">
<Border Background="LightCyan" BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding Description}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:Accordion.AccordionButtonStyle>
<toolkit:Accordion.ContentTemplate>
<DataTemplate>
<Grid>
<ScrollViewer MaxHeight="150" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" >
<ItemsControl ItemsSource="{Binding Items}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel HorizontalAlignment="Left" Margin="10"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button HorizontalContentAlignment="Left" Margin="3" Width="195" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{Binding Description}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</DataTemplate>
</toolkit:Accordion.ContentTemplate>
</toolkit:Accordion>
</Grid>
</ScrollViewer>
C#中的代码: MainPage.xaml.cs ,其属性为&#39;用于添加样本组/项目的绑定和代码:
public partial class MainPage : UserControl, INotifyPropertyChanged
{
public class ItemViewModel
{
public string Description { get; set; }
}
public class GroupViewModel
{
public List<ItemViewModel> Items { get; set; }
public string Description { get; set; }
}
public List<ItemViewModel> Items { get; set; }
public List<GroupViewModel> Groups { get; set; }
public MainPage()
{
InitializeComponent();
this.DataContext = this;
this.Groups = new List<GroupViewModel>();
GroupViewModel g1, g2, g3;
this.Groups.Add(g1 = new GroupViewModel() { Description = "Group with 4 itens", Items = new List<ItemViewModel>() });
g1.Items.Add(new ItemViewModel() { Description = "item1" } );
g1.Items.Add(new ItemViewModel() { Description = "item2" } );
g1.Items.Add(new ItemViewModel() { Description = "item3" } );
g1.Items.Add(new ItemViewModel() { Description = "item4" } );
this.Groups.Add(g2 = new GroupViewModel() { Description = "Group with 10 itens", Items = new List<ItemViewModel>() });
g2.Items.Add(new ItemViewModel() { Description = "item1" } );
g2.Items.Add(new ItemViewModel() { Description = "item2" } );
g2.Items.Add(new ItemViewModel() { Description = "item3" } );
g2.Items.Add(new ItemViewModel() { Description = "item4" } );
g2.Items.Add(new ItemViewModel() { Description = "item5" } );
g2.Items.Add(new ItemViewModel() { Description = "item6" } );
g2.Items.Add(new ItemViewModel() { Description = "item7" } );
g2.Items.Add(new ItemViewModel() { Description = "item8" } );
g2.Items.Add(new ItemViewModel() { Description = "item9" } );
g2.Items.Add(new ItemViewModel() { Description = "item10" } );
this.Groups.Add(g3 = new GroupViewModel() { Description = "Group with 3 itens", Items = new List<ItemViewModel>() });
g3.Items.Add(new ItemViewModel() { Description = "item1" } );
g3.Items.Add(new ItemViewModel() { Description = "item2" });
g3.Items.Add(new ItemViewModel() { Description = "item3" });
NotifyPropertyChanged("Groups");
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
答案 0 :(得分:1)
我找到了一个解决方案,但我不得不删除手风琴,对我来说不是什么问题。 我使用了ItemsControl作为&#34; Accordions&#39;列表&#34;使用Button作为AccordionButton。其余的保持不变,一个带有ItemsControl和WrapPanel的ScrollViewer。
ScrollViewer具有绑定到其高度。 Button有一个Command,它将ScrollViewer的高度更改为0以折叠项目,并将NaN更改为扩展。工作完美无瑕。
这是XAML:
<ItemsControl HorizontalAlignment="Stretch" VerticalAlignment="Top" ItemsSource="{Binding Groups}"
HorizontalContentAlignment="Left" VerticalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" Margin="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Command="{Binding ExpandCommand}" Content="{Binding Description}"/>
<ScrollViewer Grid.Row="1" Padding="0" VerticalScrollBarVisibility="Auto" MaxHeight="100" BorderThickness="0"
HorizontalScrollBarVisibility="Disabled" Height="{Binding ContentHeight}" HorizontalAlignment="Stretch">
<ItemsControl ItemsSource="{Binding Items}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel HorizontalAlignment="Left" Margin="10"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button HorizontalContentAlignment="Left" Margin="3" Width="80" HorizontalAlignment="Left" VerticalAlignment="Top" Content="{Binding Description}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
和xaml.cs:
public partial class MainPage : UserControl, INotifyPropertyChanged
{
public class ItemViewModel
{
public string Description { get; set; }
}
public class GroupViewModel : INotifyPropertyChanged
{
public GroupViewModel()
{
ContentHeight = double.NaN;
NotifyPropertyChanged("ContentHeight");
ExpandCommand = new DelegateCommand<object>(Expand);
}
public List<ItemViewModel> Items { get; set; }
public string Description { get; set; }
public double ContentHeight { get; set; }
public DelegateCommand<object> ExpandCommand { get; set; }
public void Expand(object obj)
{
if (double.IsNaN(this.ContentHeight)) this.ContentHeight = 0;
else this.ContentHeight = double.NaN;
NotifyPropertyChanged("ContentHeight");
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
}
public List<ItemViewModel> Items { get; set; }
public List<GroupViewModel> Groups { get; set; }
public MainPage()
{
InitializeComponent();
this.DataContext = this;
this.Groups = new List<GroupViewModel>();
GroupViewModel g1, g2, g3;
this.Groups.Add(g1 = new GroupViewModel() { Description = "Group with 4 itens", Items = new List<ItemViewModel>() });
g1.Items.Add(new ItemViewModel() { Description = "item1" } );
g1.Items.Add(new ItemViewModel() { Description = "item2" } );
g1.Items.Add(new ItemViewModel() { Description = "item3" } );
g1.Items.Add(new ItemViewModel() { Description = "item4" } );
this.Groups.Add(g2 = new GroupViewModel() { Description = "Group with 10 itens", Items = new List<ItemViewModel>() });
g2.Items.Add(new ItemViewModel() { Description = "item1" } );
g2.Items.Add(new ItemViewModel() { Description = "item2" } );
g2.Items.Add(new ItemViewModel() { Description = "item3" } );
g2.Items.Add(new ItemViewModel() { Description = "item4" } );
g2.Items.Add(new ItemViewModel() { Description = "item5" } );
g2.Items.Add(new ItemViewModel() { Description = "item6" } );
g2.Items.Add(new ItemViewModel() { Description = "item7" } );
g2.Items.Add(new ItemViewModel() { Description = "item8" } );
g2.Items.Add(new ItemViewModel() { Description = "item9" } );
g2.Items.Add(new ItemViewModel() { Description = "item10" } );
this.Groups.Add(g3 = new GroupViewModel() { Description = "Group with 3 itens", Items = new List<ItemViewModel>() });
g3.Items.Add(new ItemViewModel() { Description = "item1" } );
g3.Items.Add(new ItemViewModel() { Description = "item2" });
g3.Items.Add(new ItemViewModel() { Description = "item3" });
NotifyPropertyChanged("Groups");
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
答案 1 :(得分:0)
我觉得这并没有完全回答这个问题,但如果我删除ScrollViewers MaxHeight
属性并相反指定Wrappanel的MaxWidth
为620,则可以获得垂直视图最少有3个按钮,手风琴相应地增长/缩小没有滚动条。
权衡是当用户增加屏幕尺寸宽度时,按钮始终保持3行而忽略额外的水平空间。
<toolkit:Accordion.ContentTemplate>
<DataTemplate>
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel HorizontalAlignment="Left"
MaxWidth="620"
Margin="10" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>