Когда нажмите кнопку, чтобы отобразить группировку (прокрутите список до нужного места, но после сортировки он не выполняется

У меня есть список с использованием в качестве источника ListCollectionView

Мой ListBox использует GroupStyle, который выглядит как

<GroupBox Tag="{Binding Path=Items[0].Header}">
<GroupBox.Header>
    <TextBlock Text="{Binding Path=Items[0].Header}" FontStyle="Italic" Foreground="Gray"  FontSize="13" />
</GroupBox.Header>
<ItemsPresenter />
</GroupBox>

Применяется так

<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}"/>
</ListBox.GroupStyle>

Теперь у меня есть кнопка, которая при нажатии должна вывести на экран определенную группу (прокрутите список до нужного места)

foreach (var groupBox in FindVisualChildren<GroupBox>(this))
{
if (groupBox.Tag.ToString() == "M")
    groupBox.BringIntoView();
}

это прекрасно работает Однако, если в моем событии нажатия кнопки я меняю свой вид

MyVm.MyView.GroupDescriptions.Clear();
MyVm.MyView.SortDescriptions.Clear();
MyVm.MyView.GroupDescriptions.Add(new PropertyGroupDescription("Header"));
MyVm.MyView.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Descending));
MyVm.MyView.SortDescriptions.Add(new SortDescription("Data", ListSortDirection.Descending));

а затем сразу же снова попробуйте BringIntoView соответствующий групповой ящик, групповой ящик не найден. FindVisualChildren не находит групповые блоки, только элементы группы.

Полный код

XAML:

 <Window.Resources>
    <Style x:Key="GroupHeaderStyle" x:Shared="False" TargetType="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupItem}">
                    <GroupBox Tag="{Binding Path=Items[0].Header}">

                        <GroupBox.Header>
                            <TextBlock Text="{Binding Path=Items[0].Header}" FontStyle="Italic" Foreground="Gray" FontSize="13" />
                        </GroupBox.Header>

                        <ItemsPresenter />
                    </GroupBox>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
  </Window.Resources>

  <StackPanel Orientation="Vertical">

    <Button Click="ButtonBase_OnClick" Content="Bring M into view"></Button>
    <ScrollViewer>
        <ListBox MaxHeight="300" ItemsSource="{Binding MyView}">

            <ListBox.GroupStyle>
                <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}"/>
            </ListBox.GroupStyle>

            <ListBox.ItemTemplate>

                <DataTemplate>
                    <TextBlock Text="{Binding Data}" />
                </DataTemplate>

            </ListBox.ItemTemplate>

        </ListBox>
      </ScrollViewer>

    </StackPanel>

Код позади:

public partial class MainWindow : Window
{
    private ListVm MyVm;

    public MainWindow()
    {
        InitializeComponent();

        MyVm = new ListVm();

        DataContext = MyVm;
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        //THIS WORKS
        foreach (var groupBox in FindVisualChildren<GroupBox>(this))
        {
            if (groupBox.Tag.ToString() == "L")
                groupBox.BringIntoView();
        }

        //THIS DOES NOT

        //MyVm.MyView.GroupDescriptions.Clear();
        //MyVm.MyView.SortDescriptions.Clear();
        //MyVm.MyView.GroupDescriptions.Add(new PropertyGroupDescription("Header"));
        //MyVm.MyView.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Descending));
        //MyVm.MyView.SortDescriptions.Add(new SortDescription("Data", ListSortDirection.Descending));

        //foreach (var groupBox in FindVisualChildren<GroupBox>(this))
        //{
        //    if (groupBox.Tag.ToString() == "B")
        //        groupBox.BringIntoView();
        //}
    }

    public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

    public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
    {
        // Confirm parent and childName are valid.
        if (parent == null) return null;

        T foundChild = null;

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            // If the child is not of the request child type child
            T childType = child as T;
            if (childType == null)
            {
                // recursively drill down the tree
                foundChild = FindChild<T>(child, childName);

                // If the child is found, break so we do not overwrite the found child.
                if (foundChild != null) break;
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                // If the child's name is set for search
                if (frameworkElement != null && frameworkElement.Name == childName)
                {
                    // if the child's name is of the request name
                    foundChild = (T)child;
                    break;
                }
            }
            else
            {
                // child element found.
                foundChild = (T)child;
                break;
            }
        }

        return foundChild;
    }
   }

   public class ItemVm
  {
    public string Header { get; set; }
    public string Data { get; set; }

    public ItemVm(string data)
    {
        Data = data;
        Header = Data.Substring(0, 1);
    }
   }

   public class ListVm
   {
    public ListCollectionView MyView { get; set; }
    public ObservableCollection<ItemVm> MyList { get; set; }

    public ListVm()
    {
        MyList = new ObservableCollection<ItemVm>();

        MyList.Add(new ItemVm("Apple"));
        MyList.Add(new ItemVm("Banana"));
        MyList.Add(new ItemVm("Charlie"));
        MyList.Add(new ItemVm("Delta"));
        MyList.Add(new ItemVm("Echo"));
        MyList.Add(new ItemVm("Foxtrot"));
        MyList.Add(new ItemVm("Golf"));
        MyList.Add(new ItemVm("Hotel"));
        MyList.Add(new ItemVm("Index"));
        MyList.Add(new ItemVm("Jarjar"));
        MyList.Add(new ItemVm("Kilo"));
        MyList.Add(new ItemVm("Lima"));
        MyList.Add(new ItemVm("Monaco"));
        MyList.Add(new ItemVm("Noob"));

        MyView = (ListCollectionView)CollectionViewSource.GetDefaultView(MyList);
        MyView.GroupDescriptions.Add(new PropertyGroupDescription("Header"));
        MyView.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending));
        MyView.SortDescriptions.Add(new SortDescription("Data", ListSortDirection.Ascending));
    }
   }

0 ответов

Другие вопросы по тегам