微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当我更改选项卡并返回时,所选项目的附加属性停止工作

如何解决当我更改选项卡并返回时,所选项目的附加属性停止工作

我有一个视图和一个视图模型。我有一个 DataGrid,当我选择一行时,TextBox 显示该行的值。这只是为了显示 SelectedItems 是否被触发。

它工作正常,但如果我切换到另一个标签并返回,它就会停止工作。

我的观点:

<Window x:Class="TabControlError.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TabControlError"
        xmlns:vm="clr-namespace:TabControlError.viewmodels"
        xmlns:dp="clr-namespace:TabControlError.DependencyProperties"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <vm:MainWindowviewmodel/>
    </Window.DataContext>
    
    
    
    <Grid>
        <TabControl>
            <TabItem Header="Tab1">
                <Grid>
                    <TextBox Text="{Binding Text}" Width="100" Height="23" HorizontalAlignment="Left" VerticalAlignment="Top"/>

                    <DataGrid Margin="0,40,0"
                              ItemsSource="{Binding Numbers}"
                              SelectedItem="{Binding NumbeRSSelectedItem}"
                              dp:DataGridSelectedItemsDependencyProperty.SelectedItems="{Binding NumbeRSSelectedItems}">

                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Number" Binding="{Binding Path=.}" Width="150"/>
                        </DataGrid.Columns>
                    </DataGrid>
                </Grid>
            </TabItem>

            <TabItem Header="Tab2"/>
        </TabControl>
    </Grid>
</Window>

我的视图模型库:

using System.ComponentModel;
using System.Runtime.CompilerServices;



namespace TabControlError
{
    class viewmodelBase : INotifyPropertyChanging,INotifyPropertyChanged
    {
        #region INotifyPropertyChanging Members

        public event PropertyChangingEventHandler PropertyChanging;

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Administrative Properties

        /// <summary>
        /// Whether the view model should ignore property-change events.
        /// </summary>
        public virtual bool IgnorePropertyChangeEvents { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// Raises the PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">The name of the changed property.</param>
        
        public virtual void RaisePropertyChangedEvent([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// Raises the PropertyChanging event.
        /// </summary>
        /// <param name="propertyName">The name of the changing property.</param>
        
        public virtual void RaisePropertyChangingEvent(string propertyName)
        {
            PropertyChanging?.Invoke(this,new PropertyChangingEventArgs(propertyName));
        }

        #endregion
    }
}

我的视图模型:

using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;

namespace TabControlError.viewmodels
{
    class MainWindowviewmodel : viewmodelBase
    {
        public MainWindowviewmodel()
        {
            Numbers.Add(0);
            Numbers.Add(1);
            Numbers.Add(2);
            Numbers.Add(3);
        }




        private string _text;
        public string Text
        {
            get { return _text; }
            set
            {
                if (_text != value)
                {
                    _text = value;
                    RaisePropertyChangedEvent();
                }
            }
        }



        private ObservableCollection<long> _numbers = new ObservableCollection<long>();
        public ObservableCollection<long> Numbers
        {
            get { return _numbers; }
            set
            {
                if (_numbers != value)
                {
                    _numbers = value;
                    RaisePropertyChangedEvent();
                }
            }
        }

        private long? _numbeRSSelectedItem;
        public long? NumbeRSSelectedItem
        {
            get { return _numbeRSSelectedItem; }
            set
            {
                if (_numbeRSSelectedItem != value)
                {
                    _numbeRSSelectedItem = value;
                    RaisePropertyChangedEvent();
                }
            }
        }

        private ObservableCollection<object> _numbeRSSelectedItems = new ObservableCollection<object>();
        public ObservableCollection<object> NumbeRSSelectedItems
        {
            get { return _numbeRSSelectedItems; }
            set
            {
                
                _numbeRSSelectedItems = value;
                Text = NumbeRSSelectedItem?.ToString();
                RaisePropertyChangedEvent();
            }
        }
    }
}

我的附加财产:

using System.Windows;
using System.Collections;
using System.Windows.Controls;

namespace TabControlError.DependencyProperties
{
    class DataGridSelectedItemsDependencyProperty
    {
        #region SelectedItems
        ///
        /// SelectedItems Attached Dependency Property
        ///
        public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.Registerattached("SelectedItems",typeof(IList),typeof(DataGridSelectedItemsDependencyProperty),new FrameworkPropertyMetadata(null,FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,new PropertyChangedCallback(OnSelectedItemsChanged)));

        public static IList GetSelectedItems(DependencyObject d)
        {
            return (IList)d.GetValue(SelectedItemsProperty);
        }

        public static void SetSelectedItems(DependencyObject d,IList value)
        {
            d.SetValue(SelectedItemsProperty,value);
        }

        private static void OnSelectedItemsChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
        {
            

            
            DataGrid miDataGrid = (DataGrid)d;
            miDataGrid.SelectionChanged += DataGrid_SelectionChanged;
            miDataGrid.Unloaded += dataGrid_Unloaded;
        }

        private static void DataGrid_SelectionChanged(object sender,SelectionChangedEventArgs e)
        {
            
            DataGrid miDatagrid = (DataGrid)sender;

            //Esta variable tiene la colección del view model,o la propiedad que hace el binding al dependency property del datagrid.
            IList ModelSelectedItems = GetSelectedItems(miDatagrid);

            
            ModelSelectedItems.Clear();

            if (miDatagrid.SelectedItems != null)
            {
                foreach (var item in miDatagrid.SelectedItems)
                    ModelSelectedItems.Add(item);
            }
            SetSelectedItems(miDatagrid,ModelSelectedItems);
        }


        
        private static void dataGrid_Unloaded(object sender,RoutedEventArgs e)
        {

            DataGrid miDg = sender as DataGrid;
            miDg.SelectionChanged -= DataGrid_SelectionChanged;
            miDg.Unloaded -= dataGrid_Unloaded;
        }
        #endregion
    }
}

为什么当我更改选项卡控件中的选项卡时它停止工作?

解决方法

WPF 选项卡控件具有单个内容展示器。当您切换选项卡时,数据网格将被卸载并调用您的 Unloaded 事件处理程序,从而删除 SelectionChanged 处理程序。当你切换回来时,数据网格再次加载,但 SelectedItems 值没有改变,所以你永远不会添加 SelectionChanged 处理程序,这就是为什么它永远不会被再次调用并且项目不同步的原因.

您可以向数据网格的 Loaded 事件添加处理程序,以重新附加同步所选项目的 SelectionChanged 处理程序。例如,这样的事情应该有效:

public class DataGridSelectedItemsDependencyProperty
{
   // ...your other code.

   private static void OnSelectedItemsChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
   {
      DataGrid miDataGrid = (DataGrid)d;

      if (e.OldValue != null)
      {
         miDataGrid.SelectionChanged -= DataGrid_SelectionChanged;
         miDataGrid.Loaded -= dataGrid_Loaded;
         miDataGrid.Unloaded -= dataGrid_Unloaded;
      }

      if (e.NewValue != null)
      {
         miDataGrid.SelectionChanged += DataGrid_SelectionChanged;
         miDataGrid.Loaded += dataGrid_Loaded;
         miDataGrid.Unloaded += dataGrid_Unloaded;
      }
   }

   private static void dataGrid_Loaded(object sender,RoutedEventArgs e)
   {
      DataGrid miDataGrid = (DataGrid)sender;
      miDataGrid.SelectionChanged += DataGrid_SelectionChanged;
   }

   // ...your other code.
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。