Я знаю, что этот пост немного староват, но я подумал, что эта проблема заслуживает дальнейшего изучения.
Хотя трассировка стека теперь не имеет дополнительной строки трассировки стека ' в System.Object.GetType () ', мне удалось воспроизвести большую часть ошибок в небольшом демонстрационном приложении.
Я действительно не знаю, что вызывает это, но я сузил подозреваемых до свойства DataGrid
, ComboBox.SelectedIndex
или расширения разметки. Если я заменю любую из этих трех, проблема исчезнет или появится другая ошибка, которая более понятна.
Главное окно: (сетка данных с редактируемым столбцом)
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfApplication2"
Title="MainWindow"
Height="350"
Width="525"
>
<DataGrid ItemsSource="{Binding Items}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Column 1" Width="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Description}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedIndex="{src:ValidatedBinding SelectedIndex}"
VerticalAlignment="Center" HorizontalAlignment="Center" Width="100">
<ComboBoxItem>Not Specified</ComboBoxItem>
<ComboBoxItem>First</ComboBoxItem>
<ComboBoxItem>Second</ComboBoxItem>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Window>
Код, управляющий этим окном:
using System.Windows;
namespace WpfApplication2
{
/// <summary>
/// The main window.
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//DataContext = new Item { Description = "Item 1", SelectedIndex = 0 };
DataContext = new DemoDataContext();
}
}
/// <summary>
/// An object with 'Items'.
/// </summary>
public sealed class DemoDataContext
{
readonly Item[] _items = new Item[] {
new Item { Description = "Item 1", SelectedIndex = 0 },
new Item { Description = "Item 2", SelectedIndex = 1 },
new Item { Description = "Item 3", SelectedIndex = 2 },
};
public Item[] Items { get { return _items; } }
}
/// <summary>
/// An object with a string and an int property.
/// </summary>
public sealed class Item
{
int _selectedIndex;
string _description;
public string Description
{
get { return _description; }
set { _description = value; }
}
public int SelectedIndex
{
get { return _selectedIndex; }
set { _selectedIndex = value; }
}
}
}
Код расширения разметки:
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace WpfApplication2
{
/// <summary>
/// Creates a normal Binding but defaults NotifyOnValidationError and ValidatesOnExceptions to True,
/// Mode to TwoWay and UpdateSourceTrigger to LostFocus.
/// </summary>
[MarkupExtensionReturnType(typeof(Binding))]
public sealed class ValidatedBinding : MarkupExtension
{
public ValidatedBinding(string path)
{
Mode = BindingMode.TwoWay;
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
Path = path;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var Target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
/* on combo boxes, use an immediate update and validation */
DependencyProperty DP = Target.TargetProperty as DependencyProperty;
if (DP != null && DP.OwnerType == typeof(System.Windows.Controls.Primitives.Selector)
&& UpdateSourceTrigger == UpdateSourceTrigger.LostFocus) {
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
}
return new Binding(Path) {
Converter = this.Converter,
ConverterParameter = this.ConverterParameter,
ElementName = this.ElementName,
FallbackValue = this.FallbackValue,
Mode = this.Mode,
NotifyOnValidationError = true,
StringFormat = this.StringFormat,
ValidatesOnExceptions = true,
UpdateSourceTrigger = this.UpdateSourceTrigger
};
}
public IValueConverter Converter { get; set; }
public object ConverterParameter { get; set; }
public string ElementName { get; set; }
public object FallbackValue { get; set; }
public BindingMode Mode { get; set; }
[ConstructorArgument("path")]
public string Path { get; set; }
public string StringFormat { get; set; }
public UpdateSourceTrigger UpdateSourceTrigger { get; set; }
}
}
Когда я запускаю приложение, я вижу это:
Если я снова нажму на первый столбец, переведя ячейку в режим редактирования, я получу следующее исключение:
System.NullReferenceException не обработано HResult = -2147467261
Сообщение = Ссылка на объект не установлена для экземпляра объекта.
Source = PresentationFramework StackTrace:
в System.Windows.Data.BindingExpressionBase.ConvertValue (значение объекта,
DependencyProperty dp, Exception & e)
в System.Windows.Data.BindingExpressionBase.ConvertFallbackValue (Object
значение, DependencyProperty dp, Object sender)
в System.Windows.Data.BindingExpressionBase.get_FallbackValue ()
в System.Windows.Data.BindingExpressionBase.UseFallbackValue ()
в System.Windows.Data.BindingExpressionBase.get_Value ()
в System.Windows.Data.BindingExpressionBase.GetValue (DependencyObject d,
DependencyProperty (обрезается)
Если я упростил главное окно и удалил все, кроме ComboBox, и раскомментировал строку, которая создаст действительный элемент DataContext, тогда я получу эту ошибку:
Произошло исключение System.Windows.Markup.XamlParseException
HResult = -2146233087 Сообщение = 'Установить свойство
'System.Windows.Controls.Primitives.Selector.SelectedIndex' бросил
исключение. Номер строки «19» и позиция «39».
Source = PresentationFramework LineNumber = 19 LinePosition = 39
Трассировки стека:
at System.Windows.Markup.WpfXamlLoader.Load (XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean
skipJournaledProperties, Object rootObject, XamlObjectWriterSettings
настройки, Uri baseUri)
в System.Windows.Markup.WpfXamlLoader.LoadBaml (XamlReader xamlReader, логическое skipJournaledProperties, объект rootObject,
XamlAccessLevel accessLevel, Uri baseUri)
в System.Windows.Markup.XamlReader.LoadBaml (Потоковый поток, ParserContext parserContext, родительский объект, логическое значение closeStream)
в System.Windows.Application.LoadComponent (объектный компонент, Uri resourceLocator)
в WpfApplication2.MainWindow.InitializeComponent () в c: \ Users \ Администратор \ Documents \ Visual Studio
2012 \ Projects \ WpfApplication2 \ MainWindow.xaml: строка 1
в WpfApplication2.MainWindow..ctor () в c: \ Users \ Администратор \ Documents \ Visual Studio
2012 \ Projects \ WpfApplication2 \ MainWindow.xaml.cs: строка 12
InnerException: System.ArgumentException
HResult = -2147024809
Сообщение = 'System.Windows.Data.Binding' не является допустимым значением свойства 'SelectedIndex' .
Источник = WindowsBase
Трассировки стека:
в System.Windows.DependencyObject.SetValueCommon (DependencyProperty dp,
Значение объекта, метаданные PropertyMetadata, логическое значение
coerceWithDeferredReference, Boolean coerceWithCurrentValue,
OperationType OperationType, Boolean isInternal)
в System.Windows.DependencyObject.SetValue (DependencyProperty dp, Object
значение)
в System.Windows.Baml2006.WpfMemberInvoker.SetValue (экземпляр объекта,
Стоимость объекта)
в MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue (член XamlMember,
Объект объект, значение объекта)в MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue (Object inst,
Свойство XamlMember, значение объекта)
InnerException: