<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WPF 獲取DataGrid可見行數據

        我需要考慮如何檢測DataGrid中當前可見的行。WPF的DataGrid內部使用ScrollViewer來管理滾動,因此需要監聽ScrollViewer的ScrollChanged事件。當用戶滾動時,可以通過計算可視區域的位置來確定哪些行被顯示。在MVVM模式下,直接訪問DataGrid的行可能會破壞模式,因此需要使用附加行為或事件來將信息傳遞到ViewModel。

        目前決定構建一個附加行為類,監聽ScrollViewer的滾動事件,計算可見行,并通過依賴屬性或消息傳遞給ViewModel。

        開始建立DataGridVisibleRowsBehavior類 (注意:要通過NuGet安裝Microsoft.Xaml.Behaviors.Wpf實現附加行為)

        

          /// <summary>
          /// 獲取DataGrid可見行數據附加屬性
          /// </summary>
          public class DataGridVisibleRowsBehavior : Behavior<DataGrid>
          {
              // 綁定到ViewModel的可觀察屬性 
              public static readonly DependencyProperty VisibleItemsProperty =
                  DependencyProperty.Register("VisibleItems", typeof(IList<object>),
                      typeof(DataGridVisibleRowsBehavior),
                      new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
      
              public IList<object> VisibleItems
              {
                  get => (IList<object>)GetValue(VisibleItemsProperty);
                  set => SetValue(VisibleItemsProperty, value);
              }
      
              private ScrollViewer _scrollViewer;
              private DispatcherTimer _throttleTimer;
      
              protected override void OnAttached()
              {
                  base.OnAttached();
                  AssociatedObject.Loaded += OnLoaded;
                  _throttleTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };//延遲200毫秒刷新
                  _throttleTimer.Tick += (s, e) => UpdateVisibleItems();
              }
      
              private void OnLoaded(object sender, RoutedEventArgs e)
              {
                  _scrollViewer = FindVisualChild<ScrollViewer>(AssociatedObject);
                  if (_scrollViewer != null)
                  {
                      _scrollViewer.ScrollChanged += OnScrollChanged;
                  }
              }
      
              private void OnScrollChanged(object sender, ScrollChangedEventArgs e)
              {
                  _throttleTimer.Stop();
                  _throttleTimer.Start();
              }
      
              /// <summary>
              /// 更新行的新數據
              /// </summary>
              private void UpdateVisibleItems()
              {
                  var visibleRows = new List<object>();
                  var itemsControl = AssociatedObject;
      
                  foreach (var item in itemsControl.Items)
                  {
                      if (itemsControl.ItemContainerGenerator.ContainerFromItem(item) is DataGridRow row && IsRowVisible(row, AssociatedObject))
                      {
                          visibleRows.Add(item);
                      }
                  }
      
                  VisibleItems = visibleRows;
              }
      
              // 視覺樹遍歷方法 
              private static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
              {
                  for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
                  {
                      var child = VisualTreeHelper.GetChild(parent, i);
                      if (child is T result) return result;
                      if (FindVisualChild<T>(child) is T descendant) return descendant;
                  }
                  return null;
              }
      
              // 判斷行是否可見 
              private bool IsRowVisible(DataGridRow row, DataGrid dataGrid)
              {
                  var rowTransform = row.TransformToAncestor(dataGrid);
                  var rowRectangle = rowTransform.TransformBounds(new Rect(0, 0, row.ActualWidth, row.ActualHeight));
                  var dataGridRectangle = new Rect(0, 0, dataGrid.ActualWidth, dataGrid.ActualHeight);
                  return dataGridRectangle.IntersectsWith(rowRectangle);
              }
          }

      XAML代碼使用

      <!-- 引用命名空間 Local 是你附加屬性類所在的文件位置-->
      xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 
      xmlns:local="clr-namespace:YourNamespace.Behaviors"
       
      <!-- DataGrid定義 -->
      <DataGrid ItemsSource="{{Binding Items}}">
          <i:Interaction.Behaviors>
              <local:DataGridVisibleRowsBehavior 
                  VisibleItems="{{Binding VisibleItems, Mode=OneWayToSource}}"/>
          </i:Interaction.Behaviors>
      </DataGrid>

      ViewModel類實現(當前使用了CommunityToolkit.Mvvm來進行綁定,你也可以用其他)

      public class MainViewModel : ObservableObject 
      {
          private IList<object> _visibleItems;
          public IList<object> VisibleItems 
          {
              get => _visibleItems;
              set => SetProperty(ref _visibleItems, value);
          }
      }
      1. 節流機制:200ms延遲計算避免高頻滾動導致的性能問題
      2. 精確可視判斷:通過TransformToAncestor計算行在DataGrid中的實際位置
      3. 動態數據支持:兼容數據更新時的自動重新計算

       

        

      posted @ 2025-03-08 14:15  FalyEnd  閱讀(51)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品亚洲精品日韩精品| 无码人妻丰满熟妇片毛片| 精品无码一区二区三区电影 | 日本一区不卡高清更新二区| 日韩人妻中文字幕精品| 国产成人AV国语在线观看| 亚洲av成人无网码天堂| 狠狠综合久久久久综| 东京热人妻无码人av| 少妇人妻偷人精品视频| 免费看的一级黄色片永久| 国产欧美日韩亚洲一区二区三区| 国产成人亚洲综合图区| 真实国产老熟女无套中出 | 国产360激情盗摄全集| 亚洲中文字幕第一页在线| 激情国产一区二区三区四区| 丰满岳乱妇一区二区三区| 亚洲老熟女乱女一区二区| 国产av中文字幕精品| 麻豆成人精品国产免费| 欧洲美熟女乱又伦免费视频| 久久99久久99精品免视看动漫| 国产乱色熟女一二三四区| 成 人色 网 站 欧美大片在线观看 | 元谋县| 乱老年女人伦免费视频| 国语做受对白XXXXX在线| 福利视频在线一区二区| 日本道之久夂综合久久爱| 亚洲欧美日韩精品久久亚洲区色播| 免费现黄频在线观看国产| 久久精品国产亚洲综合av| 国产在线精品一区二区三区| 国产无遮挡真人免费视频| 国产一区二区三区在线观看免费| 美女把尿囗扒开让男人添| 亚洲 小说区 图片区 都市| 国产首页一区二区不卡| 少妇激情一区二区三区视频小说 | 国产成人无码专区|