Сценарий: Создать MarkupExtension, чтобы заменить Grid.Row =»0” Grid.Row =» {Пространство имен: ClassExtension GridRowName}»(то же самое для столбца)WPF MarkupExtension и RowDefinition результаты в NotImplementedException
Xaml Код:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" x:Name="TitleRow" />
<RowDefinition Height="Auto" x:Name="LastNameRow" />
<RowDefinition Height="Auto" x:Name="FirstNameRow" />
<RowDefinition Height="Auto" x:Name="EmailRow" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LabelColumn" />
<ColumnDefinition x:Name="ValueColumn" />
</Grid.ColumnDefinitions>
<Label Grid.Row="{me:GridDefinition Name=TitleRow}" Grid.ColumnSpan="2" FontWeight="Bold" FontSize="14" />
<Label Grid.Row="{me:GridDefinition Name=LastNameRow}" Grid.Column="{me:GridDefinition Name=LabelColumn}" FontWeight="Bold" FontSize="14" />
</Grid>
Требование:
- Показать XAML Ошибки, когда incorrent GridRowName (или ColumnName) является используется
- Показать без ошибок XAML, когда правильный GridRowName (или ColumnName) используется
- Когда Действительно ColumnName используется для объявления Row (и Vica verca) ошибка XAML должны быть показаны
проблема: Все отлично работает для Grid.Column, но Grid.Row всегда выдает «Не Реализован исключение» на этапе проектирования (Grid.Row подчеркнут , grid.colu mn нет).
Строки и столбцы называются правильными, но строка всегда показывает ошибку. Если указать неверное имя столбца, столбец показывает ошибку (которая, как ожидается, так Grid.Column работает отлично!)
Как вы можете видеть, колонка работает отлично, но Ряды не делают. Проблема лежит внутри MarkupExtension называется GridDefinitionExtension:
[MarkupExtensionReturnType(typeof(int))]
public class GridDefinitionExtension : MarkupExtension
{
public string Name { private get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
var referenceExt = new Reference(Name);
var definition = referenceExt.ProvideValue(serviceProvider);
if (definition is DefinitionBase)
{
var grid = (definition as FrameworkContentElement).Parent as Grid;
if (grid != null && definition is RowDefinition)
return grid.RowDefinitions.IndexOf(definition as RowDefinition);
if (grid != null && definition is ColumnDefinition)
return grid.ColumnDefinitions.IndexOf(definition as ColumnDefinition);
}
// This Extension only works for DefinitionBase Elements.
throw new NotSupportedException();
}
}
Исключение составляет trown на линии:
var definition = referenceExt.ProvideValue(serviceProvider);
После просмотра внутри DLL из которого вызывается метод, который я обнаружил, что тело этот метод ProvideValue выглядит следующим образом:
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
throw new ArgumentNullException("serviceProvider");
IXamlNameResolver xamlNameResolver = serviceProvider.GetService(typeof (IXamlNameResolver)) as IXamlNameResolver;
if (xamlNameResolver == null)
throw new InvalidOperationException(System.Xaml.SR.Get("MissingNameResolver"));
if (string.IsNullOrEmpty(this.Name))
throw new InvalidOperationException(System.Xaml.SR.Get("MustHaveName"));
object obj = xamlNameResolver.Resolve(this.Name);
if (obj == null)
{
string[] strArray = new string[1]
{
this.Name
};
obj = xamlNameResolver.GetFixupToken((IEnumerable<string>) strArray, true);
}
return obj;
}
Я упростил этот метод ProvideValue только показать код, это я S фактически используя в моем сценарии:
if (serviceProvider == null)
throw new ArgumentNullException("serviceProvider");
IXamlNameResolver xamlNameResolver = serviceProvider.GetService(typeof(IXamlNameResolver)) as IXamlNameResolver;
object obj = xamlNameResolver.Resolve(this.Name);
if (obj == null)
{
var strArray = new string[1]{ this.Name };
obj = xamlNameResolver.GetFixupToken((IEnumerable<string>)strArray, true);
}
return obj;
Apparantly Исключение брошено методом GetFixUpToken, но причиной этого является метод Resolve. Этот метод Resolve возвращает действительный объект при поиске ColumnDefinition по его имени, но возвращает NULL, когда делает то же самое для RowDefinition.
Ошибка брошенной GetFixUpToken является: «NotImplementedException», который, как ожидается, так как при взгляде на исходный код из IXamlNameResolver (который в этом случае имеет тип: XamlNameResolverImpl)
При взгляде на исходный код этого XamlNameResolverImpl, вы можете видеть, что метод «GetFixUpToken» пуст и бросает исключение NotImplemented (смотрите на http://dotnetinside.com/en/framework/Microsoft+Expression/Microsoft.Expression.WpfPlatform/WpfMarkupExtensionValueSetter)
public object GetFixupToken(IEnumerable<string> names, bool canAssignDirectly)
{
throw new NotImplementedException();
}
public object GetFixupToken(IEnumerable<string> names)
{
throw new NotImplementedException();
}
Но проблема в том, как я уже сказал, это Resolve вызов, который прекрасно работает для ColumnDefinition, но не для rowdefinitions ...:
Колонка:
Row:
На данный момент Я не знаю, что делать больше ...
Исходный код (пример проекта) по адресу: http://www.frederikprijck.net/stuff/MarkupExtension.rar
Просто рекомендация. Используйте фактический код в своем сообщении (например, то, что вы сделали с xaml) вместо скриншотов кода. Некоторые из этих скриншотов довольно малы при изменении размера в SO. –
Я использовал скриншот, потому что хотел указать на все проблемы: Xaml Underline, C# runtime values, ... Есть несколько скриншотов, которые я заменил кодом, так как вы правы. Думаю, я начал использовать скриншоты и забыл использовать текст там, где это возможно. Кстати, я добавил исходный проект по этой причине :-) –