【问题标题】:How to keep focus on row after reloading data in DataGrid WPF MVVM在 DataGrid WPF MVVM 中重新加载数据后如何保持对行的关注
【发布时间】:2018-11-29 06:47:52
【问题描述】:

我到处搜索,找不到答案。使用绑定到 Web API http://localhost:3000/api/profiles 的 WPF DataGrid,以及如何在重新加载数据后保持对行的关注?

public class ProfilesViewModel : BaseViewModel
    {
private ObservableCollection<Profile> _Items;
        public ObservableCollection<Profile> Profiles { get => _Items; set { _Items = value; OnPropertyChanged(); } }

public PartyProfilesViewModel()
        {
DispatcherTimer dispatcherTimer = new DispatcherTimer();
            dispatcherTimer.Tick += dispatcherTimer_Tick;
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1, 100);
            dispatcherTimer.Start();

}
private void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            var client = new RestClient("http://localhost:3000");

            var reqData = new RestRequest("api/profiles", Method.GET);
            client.ExecuteAsync(reqData, resData =>
            {
                Profiles = JsonConvert.DeserializeObject<ObservableCollection<Profile>>(resData.Content);
            });

        }

}

谢谢!

【问题讨论】:

    标签: c# wpf mvvm datagrid


    【解决方案1】:

    在 ViewModel 中为所选项目添加一个属性:

    private _currentProfile=null;
    public Profile CurrentProfile { get => _currentProfile; set { CurrentProfile = value; OnPropertyChanged(); } }
    

    扩展您的 lambda(Equals() 必须为 Profile 实现):

    client.ExecuteAsync(reqData, resData =>
    {
        var curProf = CurrentProfile;
        Profiles = JsonConvert.DeserializeObject<ObservableCollection<Profile>>(resData.Content);
        CurrentProfile=Profiles.FirstOrDefault((p)=>p.Equals(curProf));
    });
    

    并将CurrentProfile绑定到XAML中的DataGrid.SelectedItem

    <DataGrid ItemsSource="{Binding Profiles}" SelectionMode="Single" SelectedItem="{Binding CurrentProfile, Mode=TwoWay}">
    </DataGrid>
    

    【讨论】:

    • 感谢您的支持!我会试试这个并告诉你结果。
    【解决方案2】:

    我想你会发现如果你只是设置 selecteditem.你需要一个行为或代码。 这是我使用的:

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Interactivity;
    
    namespace wpf_EntityFramework
    {
        /// <summary>
        ///  Attached Behavior
        ///  Somewhat trickier than a regular behavior because it's to be attached via a style 
        /// </summary>
        class DataGridRowBehavior : Behavior<DataGridRow>
        {
            public static bool GetIsDataGridRowFocussedWhenSelected(DataGridRow dataGridRow)
            {
                return (bool)dataGridRow.GetValue(IsDataGridRowFocussedWhenSelectedProperty);
            }
    
            public static void SetIsDataGridRowFocussedWhenSelected(
              DataGridRow dataGridRow, bool value)
            {
                dataGridRow.SetValue(IsDataGridRowFocussedWhenSelectedProperty, value);
            }
    
            public static readonly DependencyProperty IsDataGridRowFocussedWhenSelectedProperty =
                DependencyProperty.RegisterAttached(
                "IsDataGridRowFocussedWhenSelected",
                typeof(bool),
                typeof(DataGridRowBehavior),
                new UIPropertyMetadata(false, OnIsDataGridRowFocussedWhenSelectedChanged));
    
            static void OnIsDataGridRowFocussedWhenSelectedChanged(
              DependencyObject depObj, DependencyPropertyChangedEventArgs e)
            {
                DataGridRow item = depObj as DataGridRow;
                if (item == null)
                    return;
    
                if (e.NewValue is bool == false)
                    return;
    
                if ((bool)e.NewValue)
                    item.Selected += OndataGridRowSelected;
                else
                    item.Selected -= OndataGridRowSelected;
            }
            static void OndataGridRowSelected(object sender, RoutedEventArgs e)
            {
                DataGridRow row = e.OriginalSource as DataGridRow;
                // If focus is already on a cell then don't focus back out of it
                if (!(Keyboard.FocusedElement is DataGridCell) && row != null)
                {
                    row.Focusable = true;
                    Keyboard.Focus(row);
                }
            }
    
        }
    }
    

    using System;
    using System.Windows.Controls;
    using System.Windows.Interactivity;
    
    namespace wpf_EntityFramework
    {
        class ScrollDataGridRowIntoView : Behavior<DataGrid>
        {
            protected override void OnAttached()
            {
    
                base.OnAttached();
                this.AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
            }
    
            void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (sender is DataGrid)
                {
                    DataGrid datagrid = (sender as DataGrid);
                    if (datagrid.SelectedItem != null)
                    {
                        datagrid.Dispatcher.BeginInvoke((Action)(() =>
                        {
                            datagrid.UpdateLayout();
                            if (datagrid.SelectedItem != null)
                            {
                                datagrid.ScrollIntoView(datagrid.SelectedItem);
                            }
                        }));
                    }
                }
            }
            protected override void OnDetaching()
            {
                base.OnDetaching();
                this.AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
            }
        }
    }
    

    用法

            <DataGrid ....
                      >
                <i:Interaction.Behaviors>
                    <local:ScrollDataGridRowIntoView />
                </i:Interaction.Behaviors>
                <DataGrid.RowStyle>
                    <Style TargetType="{x:Type DataGridRow}">
                        <Setter Property="local:DataGridRowBehavior.IsDataGridRowFocussedWhenSelected" Value="true"/>
                    </Style>
                </DataGrid.RowStyle>
    

    【讨论】:

      猜你喜欢
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-02
      相关资源
      最近更新 更多