static void Sub(object sender) { // 又由于要兼容 ItemsControl, 所以将 obj 转换为 System.Windows.Controls.Control // var source = s0 as System.Windows.Controls.Primitives.Selector; // var source = s0 as System.Windows.Controls.Control; // 虽然 ListBox / ListView / DataGrid 基类都是 Selector, 并且其结构都是 Selector => Decorator => ScrollViewer // Decorator border = System.Windows.Media.VisualTreeHelper.GetChild(source, 0) as Decorator; // ScrollViewer target = border.Child as ScrollViewer; // 但为了更加灵活, 不再规限内部的层级结构, 使用 WPFControlsUtils.FindChildOfType<T> ScrollViewer target = WPFControlsUtils.FindChildOfType <ScrollViewer>(sender as System.Windows.Controls.Control); if (target == null) { System.Diagnostics.Debug.WriteLine("找不到ScrollViewer"); System.Diagnostics.Debugger.Break(); return; } target.ScrollToEnd(); var dpDescriptor = System.ComponentModel.DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, sender.GetType()); // 为 ItemsSource 添加监控更改事件 dpDescriptor.AddValueChanged(sender, Handle_ItemsSource_Changed); }
static void Handle_ItemsSource_Changed(object s, EventArgs e) { // var source = s as System.Windows.Controls.Primitives.Selector; var scrollViewer = WPFControlsUtils.FindChildOfType <ScrollViewer>(s as System.Windows.Controls.Control); scrollViewer?.ScrollToEnd(); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); // this.PART_TextBox = VisualHelper.FindVisualElement<DatePickerTextBox>(this, "PART_TextBox_New"); this.PART_TextBox = WPFControlsUtils.FindChildOfType <DatePickerTextBox>(this, "PART_TextBox_New"); // this.PART_Popup = VisualHelper.FindVisualElement<Popup>(this, "PART_Popup_New"); this.PART_Popup = WPFControlsUtils.FindChildOfType <Popup>(this, "PART_Popup_New"); this.PART_Calendar = GetTemplateChild("PART_Calendar") as Calendar; this.PART_TimePicker = GetTemplateChild("PART_TimePicker") as TimePicker; this.PART_Clear_Button = GetTemplateChild("PART_Clear_Button") as Button; this.PART_Today_Button = GetTemplateChild("PART_Today_Button") as Button; this.PART_Confirm_Button = GetTemplateChild("PART_Confirm_Button") as Button; if (this.PART_Calendar != null) { this.PART_Calendar.AddHandler(Button.MouseLeftButtonDownEvent, new RoutedEventHandler(DayButton_MouseLeftButtonUp), true); } if (this.PART_TimePicker != null) { this.PART_TimePicker.SelectedTimeChanged += PART_TimePicker_SelectedTimeChanged;; } if (this.PART_Popup != null) { this.PART_Popup.Opened += PART_Popup_Opened; this.PART_Popup.Closed += PART_Popup_Closed; } if (this.PART_Today_Button != null) { this.PART_Today_Button.Click += PART_Today_Button_Click; } if (this.PART_Confirm_Button != null) { this.PART_Confirm_Button.Click += PART_Confirm_Button_Click; } if (this.PART_Clear_Button != null) { this.PART_Clear_Button.Click += PART_Clear_Button_Click; } }
public static DataGridCell GetGridCell(this DataGrid dataGrid, int rowIndex, int colIndex) { DataGridRow rowContainer = GetGridRow(dataGrid, rowIndex); if (rowContainer != null) { dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[colIndex]); var presenter = WPFControlsUtils.FindChildOfType <System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer); if (presenter != null) { dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[colIndex]); return((DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(colIndex)); } } return(null); }
static void Sub(object s0) { // 又由于要兼容 ItemsControl, 所以将 obj 转换为 System.Windows.Controls.Control // var source = s0 as System.Windows.Controls.Primitives.Selector; var source = s0 as System.Windows.Controls.Control; // 虽然 ListBox / ListView / DataGrid 基类都是 Selector, 并且其结构都是 Selector => Decorator => ScrollViewer // Decorator border = System.Windows.Media.VisualTreeHelper.GetChild(source, 0) as Decorator; // ScrollViewer target = border.Child as ScrollViewer; // 但为了更加灵活, 不再规限内部的层级结构, 使用 WPFControlsUtils.FindChildOfType<T> ScrollViewer target = WPFControlsUtils.FindChildOfType <ScrollViewer>(source); if (target == null) { System.Diagnostics.Debug.WriteLine("找不到ScrollViewer"); System.Diagnostics.Debugger.Break(); return; } target.ScrollChanged += Control_ScrollChanged; target.ScrollToEnd(); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); this.PART_UP = WPFControlsUtils.FindChildOfType <Button>(this, "PART_UP"); // Edit By Howe this.PART_DOWN = WPFControlsUtils.FindChildOfType <Button>(this, "PART_DOWN"); // Edit By Howe if (this.PART_UP != null) { this.PART_UP.Click += BtnUp_Click; } if (this.PART_DOWN != null) { this.PART_DOWN.Click += BtnDown_Click; } this.TextChanged += NumericUpDown_TextChanged; this.KeyUp += NumericUpDown_KeyUp; this.SetBtnEnabled(this.Value.ToString()); this.MoveCursorToEnd(); this.Value = this.CoreValueCompareMinMax(this.Value); }
/// <summary> /// 一旦你开始使用ItemsControl,你可能会遇到一个非常常见的问题:默认情况下,ItemsControl没有任何滚动条,这意味着如果内容不适合,它只是被剪裁。(From wpf-tutorial.com) /// 所以使用 ItemsControl 加上 ScrollViewer 有两种方法, /// 方法1. 外面包裹 ScrollViewer /// 方法2. 使用Template, 在Template设置 <ScrollViewer> <ItemsPresenter /> </ScrollViewer> /// </summary> private static void onHandle_IsEnabled_PropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { if (e.NewValue == null) { return; } if (sender is ScrollViewer) { var scrollViewer = sender as ScrollViewer; if ((bool)e.NewValue == true) { if (e.OldValue != null && (bool)e.OldValue == true) { return; } if (scrollViewer.Content == null) { scrollViewer.Loaded += (s0, e0) => { var target = s0 as ScrollViewer; var itemsControl = WPFControlsUtils.FindChildOfType <ItemsControl>(target); if (itemsControl != null) // 对应方法1 { var dpDescriptor = System.ComponentModel.DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, itemsControl.GetType()); dpDescriptor.AddValueChanged(itemsControl, Handle_ItemsSource_Changed_ForItemsControl); target.ScrollToEnd(); } }; return; } else { var dpDescriptor = System.ComponentModel.DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, scrollViewer.Content.GetType()); dpDescriptor.AddValueChanged(scrollViewer.Content, Handle_ItemsSource_Changed_ForItemsControl); scrollViewer.ScrollToEnd(); return; } } else // if ((bool)e.NewValue == false) { if (e.OldValue == null || (bool)e.OldValue == false) { return; } var dpDescriptor = System.ComponentModel.DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, scrollViewer.Content.GetType()); dpDescriptor.RemoveValueChanged(scrollViewer.Content, Handle_ItemsSource_Changed_ForItemsControl); return; } } // [新版] 合并 // 1. ListBox / ListView / DataGrid 基类都是 Selector // 2. ItemsControl if (sender is System.Windows.Controls.Primitives.Selector || sender is ItemsControl) { var control = sender as System.Windows.Controls.Control; ScrollViewer scrollViewer = WPFControlsUtils.FindChildOfType <ScrollViewer>(control); if ((bool)e.NewValue == true) { if (e.OldValue != null && (bool)e.OldValue == true) { return; } if (scrollViewer == null) { // 在 1. ListBox / ListView / DataGrid 中找不到 ScrollViewer // 或 2. ItemsControl 中找不到 ScrollViewer // 必须要等待加载完毕后才能找到旗下的 ScrollViewer control.Loaded += (s0, e0) => { Sub(s0); }; return; } else { Sub(control); return; } } else // if ((bool)e.NewValue == false) { if (e.OldValue == null || (bool)e.OldValue == false) { return; } UnSub(control); return; } } }
/// 一旦你开始使用ItemsControl,你可能会遇到一个非常常见的问题:默认情况下,ItemsControl没有任何滚动条,这意味着如果内容不适合,它只是被剪裁。(From wpf-tutorial.com) /// 所以使用 ItemsControl 加上 ScrollViewer 有两种方法, /// 方法1. 外面包裹 ScrollViewer /// 方法2. 使用Template, 在Template设置 <ScrollViewer> <ItemsPresenter /> </ScrollViewer> private static void onHandle_IsEnabled_PropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { if (e.NewValue == null) { return; } if (sender is ScrollViewer) // 对应方法1 { var scrollViewer = sender as ScrollViewer; if ((bool)e.NewValue == true) { if (e.OldValue != null && (bool)e.OldValue == true) { return; } scrollViewer.ScrollChanged += Control_ScrollChanged; scrollViewer.ScrollToEnd(); return; } else // if ((bool)e.NewValue == false) { if (e.OldValue == null || (bool)e.OldValue == false) { return; } scrollViewer.ScrollChanged -= Control_ScrollChanged; return; } } #region [旧版] //// ListBox / ListView / DataGrid 基类都是 Selector //if (sender is System.Windows.Controls.Primitives.Selector selector) //{ // ScrollViewer scrollViewer = WPFControlsUtils.FindChildOfType<ScrollViewer>(selector); // if ((bool)e.NewValue == true) // { // if (e.OldValue != null && (bool)e.OldValue == true) { return; } // if (scrollViewer == null) // { // // 在 ListBox / ListView / DataGrid 中找不到 ScrollViewer // // 必须要等待加载完毕后才能找到旗下的 ScrollViewer // selector.Loaded += (s0, e0) => { Sub(s0); }; // return; // } // else // { // Sub(selector); // return; // } // } // else // // if ((bool)e.NewValue == false) // { // if (e.OldValue == null || (bool)e.OldValue == false) { return; } // UnSub(scrollViewer); // return; // } //} //if (sender is ItemsControl itemsControl) // 对应方法2 // 此处其实可以合并到上面的 if 中 ==> if //{ // ScrollViewer scrollViewer = WPFControlsUtils.FindChildOfType<ScrollViewer>(itemsControl); // if ((bool)e.NewValue == true) // { // if (e.OldValue != null && (bool)e.OldValue == true) { return; } // if (scrollViewer == null) // { // // 在 ItemsControl 中找不到 ScrollViewer // // 必须要等待加载完毕后才能找到旗下的 ScrollViewer // itemsControl.Loaded += (s0, e0) => { Sub(s0); }; // return; // } // else // { // Sub(itemsControl); // return; // } // } // else // // if ((bool)e.NewValue == false) // { // if (e.OldValue == null || (bool)e.OldValue == false) { return; } // UnSub(scrollViewer); // return; // } //} #endregion // 新版 将旧版2种情况合并起来 // 1. ListBox / ListView / DataGrid 基类都是 Selector // 2. ItemsControl if (sender is System.Windows.Controls.Primitives.Selector || sender is ItemsControl) { var control = sender as System.Windows.Controls.Control; ScrollViewer scrollViewer = WPFControlsUtils.FindChildOfType <ScrollViewer>(control); if ((bool)e.NewValue == true) { if (e.OldValue != null && (bool)e.OldValue == true) { return; } if (scrollViewer == null) { // 在 1. ListBox / ListView / DataGrid 中找不到 ScrollViewer // 或 2. ItemsControl 中找不到 ScrollViewer // 必须要等待加载完毕后才能找到旗下的 ScrollViewer control.Loaded += (s0, e0) => { Sub(s0); }; return; } else { Sub(control); return; } } else // if ((bool)e.NewValue == false) { if (e.OldValue == null || (bool)e.OldValue == false) { return; } UnSub(scrollViewer); return; } } }
void Test3(object obj) { var scrollViewer = WPFControlsUtils.FindChildOfType <System.Windows.Controls.ScrollViewer>(obj as DataGrid); }