/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace CommonWPF {
///
/// Generic Visual helper.
///
public static class VisualHelper {
///
/// Find a child object in a WPF visual tree.
///
///
/// Sample usage:
/// GridViewHeaderRowPresenter headerRow = listView.GetVisualChild<GridViewHeaderRowPresenter>();
///
/// From https://social.msdn.microsoft.com/Forums/vstudio/en-US/7d0626cb-67e8-4a09-a01e-8e56ee7411b2/gridviewcolumheader-radiobuttons?forum=wpf
///
///
///
///
public static T GetVisualChild(this Visual referenceVisual) where T : Visual {
Visual child = null;
for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceVisual); i++) {
child = VisualTreeHelper.GetChild(referenceVisual, i) as Visual;
if (child != null && child is T) {
break;
} else if (child != null) {
child = GetVisualChild(child);
if (child != null && child is T) {
break;
}
}
}
return child as T;
}
}
///
/// Add functions to get the element that's currently shown at the top of the ListView
/// window, and to scroll the list so that a specific item is at the top.
///
public static class ListViewExtensions {
///
/// Figures out which item index is at the top of the window. This only works for a
/// ListView with a VirtualizingStackPanel.
///
/// The item index, or -1 if the list is empty.
public static int GetTopItemIndex(this ListView lv) {
if (lv.Items.Count == 0) {
return -1;
}
VirtualizingStackPanel vsp = lv.GetVisualChild();
if (vsp == null) {
Debug.Assert(false, "ListView does not have a VirtualizingStackPanel");
return -1;
}
return (int) vsp.VerticalOffset;
}
///
/// Scrolls the ListView so that the specified item is at the top. The standard
/// ListView.ScrollIntoView() makes the item visible but doesn't ensure a
/// specific placement.
///
///
/// Equivalent to setting myListView.TopItem in WinForms.
///
public static void ScrollToTopItem(this ListView lv, object item) {
ScrollViewer sv = lv.GetVisualChild();
sv.ScrollToBottom();
lv.ScrollIntoView(item);
}
}
}