我正在尝试对一系列行进行数据绑定,并对它们执行排序功能,并在排序完成后更新UI(以显示排序算法的差异)。>
我有一个基本的WPF应用程序,该应用程序由绑定到对象集合的ItemsControl组成。这些对象在第一次渲染屏幕时已正确绑定,但是一旦排序操作完成,基础列表就已经正确排序了,但是UI尚未重绘?
这是我的XAML
<Grid>
<Button Content="Sort" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="12" MinWidth="80" Click="Button_Click"/>
<ItemsControl x:Name="mainControl" ItemsSource="{Binding Values}" ItemTemplate="{StaticResource LineDataTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter" />
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
有一个xaml数据模板
<DataTemplate x:Key="LineDataTemplate">
<Line X1="{Binding X1}" Y1="{Binding Y1}"
X2="{Binding X2}" Y2="{Binding Y2}"
Stroke="DarkGray" StrokeThickness="3"/>
</DataTemplate>
主数据上下文包含此Line对象的列表
public class Line
{
public int X1 { get; set; }
public int Y1 { get; set; }
public int X2 { get; set; }
public int Y2 { get; set; }
}
当初始化数据上下文时,我会创建一些随机行
private void RandomiseLines()
{
var rnd = new Random();
var startingPoint = 2;
Values = new List<Line>();
for (int i = 0; i < 3; i++)
{
Values.Add(new Line() { X1 = startingPoint, Y1 = 420, X2 = startingPoint, Y2 = (420 - rnd.Next(1, 300)) });
startingPoint += 4;
}
}
然后我在UI上有一个按钮,该按钮通过linq调用并(现在)调用基本排序
Values = Values.OrderBy(x => x.Y2).ToList();
保存此列表的数据上下文实现INotifiedProperty更改的接口,对列表进行排序后,我将调用Property更改事件。尽管对底层列表进行了排序,但UI似乎没有重新绘制,但我尝试使用ObservableCollection并在Dispatcher中进行包装,但是似乎没有抛出任何绑定错误或异常。谁能解释为什么它没有更新?
编辑:添加了预期结果 预期结果将是ItemsControl重绘自身,并且行将按照新的排序顺序
答案 0 :(得分:1)
最好使用Rectangle
而不是Line
,因为它不依赖于坐标进行定位。您只给他们一个共享的Width
,但给他们一个变量Hight
。 ItemsPanel
应该是StackPanel
设置为StackPanel.Orientation
的{{1}}。值集合必须为Horizontal
。然后它应该表现出预期的效果。
这样,条形的顺序将反映集合的顺序。
主视图
ObservableCollection<double>
<StackPanel>
<Button Content="Sort"
Click="Button_Click" />
<ItemsControl x:Name="mainControl"
ItemsSource="{Binding Values}"
ItemTemplate="{DynamicResource LineDataTemplate}">
<ItemsControl.Resources>
<DataTemplate x:Key="LineDataTemplate" DataType="system:Double">
<Rectangle Width="5"
Height="{Binding}"
VerticalAlignment="Bottom"
Fill="DarkGray"
Margin="0,0,3,0" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
事件处理程序
Button.Click
视图模型
private void Button_Click(object sender, RoutedEventArgs e)
{
var viewModel = this.DataContext as TestViewModel;
var orderedValues = viewModel.Values.OrderBy(value => value).ToList();
viewModel.Values = new ObservableCollection<double>(orderedValues);
}