Почему привязка данных к холсту не обновляет интерфейс - PullRequest
1 голос
/ 08 июля 2019

enter image description here Я пытаюсь привязать данные к набору строк, выполнить на них функцию сортировки и обновить пользовательский интерфейс после завершения сортировки (хотелось бы показать различия в алгоритмах сортировки).

У меня есть базовое приложение WPF, которое состоит из ItemsControl, который связан с коллекцией объектов.Эти объекты правильно привязываются при первом отображении экрана, однако после завершения операции сортировки базовый список был отсортирован правильно, но пользовательский интерфейс не был перерисован?

Вот мой 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;
    }
}

Затем у меня есть кнопка в пользовательском интерфейсе, которая вызывает и (на данный момент) вызывает базовую сортировку, используя linq

Values = Values.OrderBy(x => x.Y2).ToList();

Контекст данных, где этот списокудерживает реализует измененный интерфейс INotifiedProperty, и как только список отсортирован, я вызываю событие «Изменено свойство».Хотя основной список отсортирован, пользовательский интерфейс, кажется, не перерисовывается, я попытался использовать ObservableCollection и перенос в Dispatcher, но у меня, похоже, нет каких-либо ошибок или исключений привязки.Кто-нибудь может объяснить, почему это не обновляется?

Редактировать: Добавлен ожидаемый результат Ожидаемым результатом будет перерисовка ItemsControl, и строки будут вновый отсортированный заказ

1 Ответ

1 голос
/ 08 июля 2019

Лучше использовать Rectangle вместо Line, потому что он не зависит от координат для позиционирования.Вы просто даете им общую Width, но переменную Hight.ItemsPanel должно быть StackPanel с StackPanel.Orientation, установленным на 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);
}

Представление модели

private void RandomiseLines()
{
    var rnd = new Random();

    Values = new ObservableCollection<double>();

    for (int i = 0; i < 3; i++)
    {
        Values.Add(rnd.Next(1, 300));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...