如何解决当我更改选项卡并返回时,所选项目的附加属性停止工作
我有一个视图和一个视图模型。我有一个 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 举报,一经查实,本站将立刻删除。