为什么绑定到画布的数据无法更新UI

时间:2019-07-08 10:18:04

标签: c# wpf data-binding

enter image description here我正在尝试对一系列行进行数据绑定,并对它们执行排序功能,并在排序完成后更新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重绘自身,并且行将按照新的排序顺序

1 个答案:

答案 0 :(得分:1)

最好使用Rectangle而不是Line,因为它不依赖于坐标进行定位。您只给他们一个共享的Width,但给他们一个变量HightItemsPanel应该是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);
}