我有一个WPF ListView,其中包含多个具有WrapPanels的ItemsControl。 只要没有可见的滚动条,项目就会按预期进行换行。当有可见的滚动条时,当窗口变得不那么宽时,我可以看到WrapPanel声明需要移动到左侧列的项目的垂直空间,但项目不移动。使用滚动条滚动后,项目会跳转到正确的列。
有没有人遇到这个并且有人知道解决方案吗?
电影剪辑会更清晰,但在下面的图片中,我尝试解释步骤和发生的事情。该项目的代码发布在图片下方。
没有滚动条,包装工作正常
没有滚动条,甚至更窄的窗口,包装仍然可以正常工作:
滚动条可见,包装仍然正常:
滚动条可见,屏幕较窄,绿色包装纸显示要移动到最左侧列的项目声明垂直空间,但项目不移动:
使用滚动条后,项目会跳转到正确的列:
MainWindow.xaml
<Window x:Class="Wrapping.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="800" Width="600">
<Window.Resources>
<DataTemplate x:Key="DetailReadOnlyTemplate">
<Grid Width="75" Height="15" Margin="2" Background="Green"/>
</DataTemplate>
<DataTemplate x:Key="MainObjectReadOnlyTemplate">
<StackPanel>
<Grid VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Number}"/>
<TextBlock Text="Some text" Grid.Column="1" HorizontalAlignment="Right"/>
</Grid>
<ItemsControl ItemsSource="{Binding DetailObjects}"
ItemTemplate="{StaticResource DetailReadOnlyTemplate}"
Background="LightGreen">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</DataTemplate>
</Window.Resources>
<ListView ItemsSource="{Binding MainObjects}"
SelectedItem="{Binding SelectedMainObject}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemTemplate="{StaticResource MainObjectReadOnlyTemplate}"
HorizontalContentAlignment="Stretch"
Background="Bisque"/>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : INotifyPropertyChanged
{
private static readonly Random Random = new Random();
public MainWindow()
{
DataContext = this;
InitializeComponent();
MainObjects = new ObservableCollection<MainObject>();
for (var i = 0; i < 10; i++)
{
MainObjects.Add(CreateMainObject(i));
}
}
private ObservableCollection<MainObject> _mainObjects;
public ObservableCollection<MainObject> MainObjects
{
get => _mainObjects;
set
{
_mainObjects = value;
OnPropertyChanged();
}
}
private MainObject _selectedMainObject;
public MainObject SelectedMainObject
{
get => _selectedMainObject;
set
{
_selectedMainObject = value;
OnPropertyChanged();
}
}
private MainObject CreateMainObject(int n)
{
return new MainObject
{
DisplayText = "Main object " + n,
Number = n,
DetailObjects = GenerateDetailObjects()
};
}
private ObservableCollection<DetailObject> GenerateDetailObjects()
{
var detailObjects = new ObservableCollection<DetailObject>();
for (var i = 0; i < Random.Next(2, 4); i++)
{
detailObjects.Add(new DetailObject
{
DisplayText = "Detail " + i,
Value = GenerateRandomString(Random.Next(3, 8))
});
}
return detailObjects;
}
public static string GenerateRandomString(int length)
{
const string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
return new string(Enumerable.Repeat(chars, length).Select(s => s[Random.Next(s.Length)]).ToArray());
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
虚拟对象:
public class MainObject : INotifyPropertyChanged
{
private int _number;
public int Number
{
get => _number;
set
{
_number = value;
OnPropertyChanged();
}
}
private string _displayText;
public string DisplayText
{
get => _displayText;
set
{
_displayText = value;
OnPropertyChanged();
}
}
private ObservableCollection<DetailObject> _detailObjects;
public ObservableCollection<DetailObject> DetailObjects
{
get => _detailObjects;
set
{
_detailObjects = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class DetailObject : INotifyPropertyChanged
{
private string _displayText;
public string DisplayText
{
get => _displayText;
set
{
_displayText = value;
OnPropertyChanged();
}
}
private string _value;
public string Value
{
get => _value;
set
{
_value = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
答案 0 :(得分:1)
事实证明,ListView不是很擅长滚动。禁用外部ListView上的滚动条并将其包装在ScrollViewer中后,内部WrapPanel和包含的项按预期运行。我花了一天时间来弄明白这一点。