Bất cứ khi nào một nút được chọn trong treeview của tôi, nó sẽ tự động cuộn ngang cho mục đó. Có cách nào để tắt tính năng này không?Ngăn cuộn ngang tự động trong TreeView
Trả lời
Xử lý sự kiện RequestBringIntoView và đặt Được xử lý thành đúng và khung sẽ không cố gắng đưa mục đó vào chế độ xem. Ví dụ, làm một cái gì đó như thế này trong XAML của bạn:
<TreeView>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<EventSetter Event="RequestBringIntoView" Handler="TreeViewItem_RequestBringIntoView"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Và sau đó này trong code-behind:
private void TreeViewItem_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
e.Handled = true;
}
tôi quản lý để giải quyết vấn đề bằng cách sử dụng sau đây:
<TreeView ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<TreeView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=ContentPresenter, AncestorLevel=1}}" />
</ItemsPanelTemplate>
</TreeView.ItemsPanel>
</TreeView>
Tôi ràng buộc chiều rộng của StackPanel mà ám ItemsPanel ở đây, đến ActualWidth của ContentPresenter trong TreeView.
Nó cũng hoạt động tốt với TreeView kéo dài "hacked" bởi: http://blogs.msdn.com/b/jpricket/archive/2008/08/05/wpf-a-stretching-treeview.aspx (Tôi sửa đổi giải pháp đó để không loại bỏ cột lưới, nhưng để thay đổi thuộc tính Grid.Column của phần tử Decorator đầu tiên từ 1 đến 2).
Tuyệt vời! Cảm ơn! – John
Matthew, tôi đã bảo quản cuộn dọc và chỉ ngăn cuộn ngang bằng cách khôi phục vị trí ngang sau khi cuộn do sự kiện RequestBringIntoView gây ra.
private double treeViewHorizScrollPos = 0.0;
private bool treeViewResetHorizScroll = false;
private ScrollViewer treeViewScrollViewer = null;
private void TreeViewItemRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
if (this.treeViewScrollViewer == null)
{
this.treeViewScrollViewer = this.DetailsTree.Template.FindName("_tv_scrollviewer_", this.DetailsTree) as ScrollViewer;
if(this.treeViewScrollViewer != null)
this.treeViewScrollViewer.ScrollChanged += new ScrollChangedEventHandler(this.TreeViewScrollViewerScrollChanged);
}
this.treeViewResetHorizScroll = true;
this.treeViewHorizScrollPos = this.treeViewScrollViewer.HorizontalOffset;
}
private void TreeViewScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (this.treeViewResetHorizScroll)
this.treeViewScrollViewer.ScrollToHorizontalOffset(this.treeViewHorizScrollPos);
this.treeViewResetHorizScroll = false;
}
Tuyệt vời. sử dụng e.Handled = true; đã không làm việc cho tôi, nhưng bạn chắc chắn sẽ làm điều đó! – mdiehl13
Tôi có DataGrid mà tôi muốn thực hiện thao tác tương tự và sử dụng câu trả lời của POHB chủ yếu. Tôi đã phải sửa đổi nó cho giải pháp của tôi. Các mã được hiển thị dưới đây. DataGrid là một DataGrid 2 x 2 với cột đầu tiên là mỏng và thứ hai là rất rộng (1000+). Cột đầu tiên bị đóng băng. Tôi hy vọng điều này sẽ giúp ai đó ra ngoài. -Matt
public partial class MyUserControl : UserControl
{
private ScrollContentPresenter _scrollContentPresenter;
private ScrollViewer _scrollViewer;
private double _dataGridHorizScrollPos = 0.0;
private bool _dataGridResetHorizScroll = false;
public MyUserControl()
{
// setup code...
_dataGrid.ApplyTemplate();
_scrollViewer = FindVisualChild<ScrollViewer>(_dataGrid);
_scrollViewer.ScrollChanged += new ScrollChangedEventHandler(DataGridScrollViewerScrollChanged);
_scrollContentPresenter = FindVisualChild<ScrollContentPresenter>(_scrollViewer);
_scrollContentPresenter.RequestBringIntoView += new RequestBringIntoViewEventHandler(_scrollContentPresenter_RequestBringInputView);
}
private void DataGridScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (_dataGridResetHorizScroll)
{
_scrollViewer.ScrollToHorizontalOffset(_dataGridHorizScrollPos);
}
// Note: When the row just before a page change is selected and then the next row on the
// next page is selected, a second event fires setting the horizontal offset to 0
// I'm ignoring those large changes by only recording the offset when it's large. -MRB
else if (Math.Abs(e.HorizontalChange) < 100)
{
_dataGridHorizScrollPos = _scrollViewer.HorizontalOffset;
}
_dataGridResetHorizScroll = false;
}
public T FindVisualChild<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 ScrollViewer))
{
// I needed this since the template wasn't applied yet when
// calling from the constructor
(child as ScrollViewer).ApplyTemplate();
}
if (child != null && child is T)
{
return (T)child;
}
T childItem = FindVisualChild<T>(child);
if (childItem != null) return childItem;
}
}
return null;
}
private void _scrollContentPresenter_RequestBringInputView(object sender, RequestBringIntoViewEventArgs e)
{
_dataGridResetHorizScroll = true;
}
Tôi gặp sự cố tương tự. Tôi cần thiết để ngăn cuộn ngang nhưng vẫn giữ được cuộn dọc. Giải pháp của tôi là xử lý phương thức OnRequestBringIntoView
như tôi muốn nó hoạt động. Tôi đã tạo một ResourceDictionary
cho số TreeViewItem
và thêm EventSetters
cho các phương thức OnSelected
và OnRequestBringIntoView
.
MyResourceDictionary.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:Class="Resources.MyResourceDictionary" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TreeViewItem" x:Key="treeitem" >
<EventSetter Event="RequestBringIntoView" Handler="OnRequestBringIntoView"/>
<EventSetter Event="Selected" Handler="OnSelected"/>
</Style>
</ResourceDictionary>
MyResourceDictionary.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace Resources
{
partial class MyResourceDictionary:ResourceDictionary
{
public MyResourceDictionary()
{
InitializeComponent();
}
private void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
e.Handled = true; //prevent event bubbling
var item = (TreeViewItem)sender;
TreeView tree = GetParentTree(item) as TreeView;
if(tree!=null)
{
var scrollViewer = tree.Template.FindName("_tv_scrollviewer_", tree) as ScrollViewer;
if (scrollViewer != null)
{
scrollViewer.ScrollToLeftEnd();//prevent horizontal scroll
Point relativePoint = item.TransformToAncestor(tree).Transform(new Point(0, 0));//get position of a selected item
if (relativePoint.Y <= scrollViewer.ContentVerticalOffset) return;//do no scroll if we select inside one 'scroll screen'
scrollViewer.ScrollToVerticalOffset(relativePoint.Y);//scroll to Y of a selected item
}
}
}
private DependencyObject GetParentTree(DependencyObject item)
{
var target = VisualTreeHelper.GetParent(item);
return target as TreeView != null ? target : GetParentTree(target);
}
private void OnSelected(object sender, RoutedEventArgs e) //handle programmatically selected items
{
var item = (TreeViewItem)sender;
item.BringIntoView();
e.Handled = true;
}
}
}
@ giải pháp lena của việc bảo tồn di chuyển dọc làm việc tốt nhất cho tôi. Tôi đã lặp lại nó một chút:
private void TreeViewItem_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
var treeViewItem = (TreeViewItem)sender;
var scrollViewer = treeView.Template.FindName("_tv_scrollviewer_", treeView) as ScrollViewer;
Point topLeftInTreeViewCoordinates = treeViewItem.TransformToAncestor(treeView).Transform(new Point(0, 0));
var treeViewItemTop = topLeftInTreeViewCoordinates.Y;
if (treeViewItemTop < 0
|| treeViewItemTop + treeViewItem.ActualHeight > scrollViewer.ViewportHeight
|| treeViewItem.ActualHeight > scrollViewer.ViewportHeight)
{
// if the item is not visible or too "tall", don't do anything; let them scroll it into view
return;
}
// if the item is already fully within the viewport vertically, disallow horizontal scrolling
e.Handled = true;
}
Điều này làm cho ScrollViewer cuộn bình thường nếu mặt hàng đó không có trong khung nhìn theo chiều dọc. Tuy nhiên đối với trường hợp "gây phiền nhiễu" thực tế (trong đó mục đã hiển thị), nó đặt e.Handled thành true, do đó ngăn cản việc di chuyển ngang.
Để cung cấp một phiên bản hơi đơn giản của câu trả lời @ lena của:
Để cuộn theo chiều dọc trong khi vẫn giữ vị trí cuộn ngang, và không có tác dụng phụ không mong muốn, trong XAML, thêm xử lý sự kiện cho RequestBringIntoView và chọn:
<TreeView>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<EventSetter Event="RequestBringIntoView" Handler="TreeViewItem_RequestBringIntoView"/>
<EventSetter Event="Selected" Handler="OnSelected"/>
...
Trong đoạn mã phía sau, thêm hai xử lý sự kiện:
private void TreeViewItem_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
// Ignore re-entrant calls
if (mSuppressRequestBringIntoView)
return;
// Cancel the current scroll attempt
e.Handled = true;
// Call BringIntoView using a rectangle that extends into "negative space" to the left of our
// actual control. This allows the vertical scrolling behaviour to operate without adversely
// affecting the current horizontal scroll position.
mSuppressRequestBringIntoView = true;
TreeViewItem tvi = sender as TreeViewItem;
if (tvi != null)
{
Rect newTargetRect = new Rect(-1000, 0, tvi.ActualWidth + 1000, tvi.ActualHeight);
tvi.BringIntoView(newTargetRect);
}
mSuppressRequestBringIntoView = false;
}
private bool mSuppressRequestBringIntoView;
// Correctly handle programmatically selected items
private void OnSelected(object sender, RoutedEventArgs e)
{
((TreeViewItem)sender).BringIntoView();
e.Handled = true;
}
- 1. C# WinForms TreeView xóa Thanh cuộn ngang
- 2. jQuery prepend - ngăn chặn tự động cuộn
- 3. Cuộn ngang - Di động - vuốt?
- 4. tắt cuộn ngang trên web di động
- 5. Sự cố cuộn trong TreeView ảo hóa
- 6. Làm cách nào để ngăn trình soạn thảo Visual Studio tự động cuộn ngang khi điểm ngắt được nhấn
- 7. RichTextBox cuộn ngang không hoạt động
- 8. Cuộn ngang?
- 9. Cuộn ngang, ngang và dọc cho GridLayout
- 10. GridView với cuộn ngang
- 11. dừng cuộn ngang trong JTextArea
- 12. Cuộn ngang trong mục ListView?
- 13. Hình thái: Tự động thay đổi kích thước hộp nhóm chứa trong ngăn cuộn?
- 14. DIV tự động cuộn
- 15. thanh cuộn ngang cho ul
- 16. javafx tableview tự động cuộn đến
- 17. Cuộn ngang jQuery (nhấp và tạo ảnh động)
- 18. Cuộn ngang Div
- 19. jqGrid thanh cuộn ngang
- 20. Div với cuộn ngang chỉ
- 21. Cuộn ngang vô hạn UIScrollView
- 22. Thanh cuộn ngang không hoạt động trên thẻ được chọn
- 23. Tự động cuộn một Textarea
- 24. Cách tạo UITabBar cuộn ngang trong iOS?
- 25. Cuộn ngang Xem bên trong ViewPager
- 26. WPF: Ảo hóa TreeView không hoạt động
- 27. Dọc Scrollbar dẫn đến thanh cuộn ngang
- 28. Sắp xếp TreeView Tự động khi thêm các nút
- 29. tự động cuộn xuống dưới khi tự động tràn
- 30. Bảng cuộn ngang của iPhone
có cách nào để bảo tồn di chuyển theo chiều dọc, và chỉ ngăn chặn horiz ontal di chuyển? –
cho @MatthewPirocchi và những người khác có cùng vấn đề: có vẻ như tôi đã tìm thấy giải pháp http://stackoverflow.com/a/34269542/692829 – lena
Giải pháp mới, đơn giản hơn để cho phép cuộn dọc mà không thay đổi bù cuộn ngang (với không có tác dụng phụ không mong muốn), xem câu trả lời này: http://stackoverflow.com/questions/3225940/prevent-automatic-horizontal-scroll-in-treeview/34269542#42238409 –