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



我有一个视图和一个视图模型。我有一个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,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
}
}

My view model:

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.
}

相关内容

  • 没有找到相关文章

最新更新