Я испытываю очень странное поведение с ItemTemplate ItemsControl. Некоторые из BindingExperssions возвращают null, хотя DataContext.WPF: BindingExpression возвращает null, хотя свойство source имеет значение
Вот XAML в вопросе:
<ItemsControl ItemsSource="{Binding Path=Index}" Grid.Row="1" Grid.Column="0" x:Name="RowsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type models:IndexCell}">
<Border Style="{StaticResource CellBorderStyle}"
Background="{Binding BackgroundColor, Converter={StaticResource ColorToBrushConverter}}"
ToolTip="{Binding Path=ToolTip}">
<TextBlock Text="{Binding Path=Content}" MouseDown="TextBlock_MouseDown"
HorizontalAlignment="{Binding Path=HorizontalTextAlignment}"
VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Так, например, я могу видеть, что визуально Контент свойство из DataContext извлекается. Значения I планирующие действительно показаны на screen.However, HorizontalTextAlignment выдает ошибку в окне Output в Visual Studio:
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=HorizontalTextAlignment; DataItem='IndexCell' (HashCode=40508359); target element is 'TextBlock' (Name=''); target property is 'HorizontalAlignment' (type 'HorizontalAlignment')
Свойства в объекте DataContext имеет правильный тип (System.Windows.HorizontalAlignment) и значение (я установил один по умолчанию, и это перечисление, так что «нет шанса» быть нулевым).
Я также провел еще один тест с IValueConverter. Когда Path указывается в Binding, конвертер получает нуль. Когда пути нет, он получает весь объект, и я его отлаживал, и он имеет значение для свойства. Кажется, что в WPF есть ошибка, но я действительно надеюсь, что я ошибаюсь.
У кого-нибудь есть идея, почему и как это происходит? Может, как я могу это исправить?
EDIT (по запросу): Вот интерфейс объекта DataContext
public interface ICell
{
string Content { get; set; }
Color TextColor { get; set; }
Color BackgroundColor { get; set; }
double FontSize { get; set; }
FontWeight FontWeight { get; set; }
TextWrapping TextWrapping { get; set; }
HorizontalAlignment HorizontalTextAlignment { get; set; }
VerticalAlignment VerticalTextAlignment { get; set; }
string ToolTip { get; set; }
}
И ItemsSource собственности из ViewModel:
private IReadOnlyList<ICell> _index;
public IReadOnlyList<ICell> Index
{
get { return _index; }
private set
{
if (_index == value)
return;
_index = value;
RaisePropertyChanged();
}
}
EDIT2: Вот код BasicCell
public abstract class BasicCell : BasicProxyElement, ICell
{
[StyleProperty]
public Color BackgroundColor
{
get
{
return this.GetProperty<Color>("BackgroundColor", Color.FromArgb(0, 0, 0, 0));
}
set
{
if (value == BackgroundColor)
{
return;
}
if (this.TrySetProperty("BackgroundColor", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public string Content
{
get
{
return this.GetProperty<string>("Content", "");
}
set
{
if (value == Content)
{
return;
}
if (this.TrySetProperty("Content", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public double FontSize
{
get
{
return this.GetProperty<double>("FontSize", 11d);
}
set
{
if (value == FontSize)
{
return;
}
if (this.TrySetProperty("FontSize", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public FontWeight FontWeight
{
get
{
return this.GetProperty<FontWeight>("FontWeight", FontWeights.Normal);
}
set
{
if (value == FontWeight)
{
return;
}
if (this.TrySetProperty("FontWeight", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public HorizontalAlignment HorizontalTextAlignment
{
get
{
return this.GetProperty<HorizontalAlignment>("HorizontalTextAlignment", HorizontalAlignment.Center);
}
set
{
if (value == HorizontalTextAlignment)
{
return;
}
if (this.TrySetProperty("HorizontalTextAlignment", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public Color TextColor
{
get
{
return this.GetProperty<Color>("TextColor", Color.FromArgb(255, 0, 0, 0));
}
set
{
if (value == TextColor)
{
return;
}
if (this.TrySetProperty("TextColor", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public TextWrapping TextWrapping
{
get
{
return this.GetProperty<TextWrapping>("TextWrapping", TextWrapping.Wrap);
}
set
{
if (value == TextWrapping)
{
return;
}
if (this.TrySetProperty("TextWrapping", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public string ToolTip
{
get
{
return this.GetProperty<string>("ToolTip", null);
}
set
{
if (value == ToolTip)
{
return;
}
if (this.TrySetProperty("ToolTip", value))
{
this.RaisePropertyChanged();
}
}
}
[StyleProperty]
public VerticalAlignment VerticalTextAlignment
{
get
{
return this.GetProperty<VerticalAlignment>("VerticalTextAlignment", VerticalAlignment.Center);
}
set
{
if (value == VerticalTextAlignment)
{
return;
}
if (this.TrySetProperty("VerticalTextAlignment", value))
{
this.RaisePropertyChanged();
}
}
}
public BasicCell(IGraphElement dataElement, IProxyGraph graph, string visualTarget) : base(dataElement, graph, visualTarget)
{
}
}
и Индекс:
public class IndexCell : BasicCell
{
private static readonly IProxyElementFactory _factory = new DelegateProxyElementFactory("IndexCell",
(graphElement, controller, visualTarget) => new IndexCell(graphElement, controller, visualTarget));
public static IProxyElementFactory Factory
{
get { return _factory; }
}
private static readonly IStyleProvider _styleProvider = new ReflectionDefaultStyleProvider<IndexCell>();
public static IStyleProvider StyleProvider
{
get { return _styleProvider; }
}
public IndexCell(IGraphElement dataElement, IProxyGraph graph, string visualTarget) : base(dataElement, graph, visualTarget)
{
}
}
спасибо!
Не могли бы вы включить соответствующий код в конец –
Кажется, что он работает нормально. Как вы строите коллекцию? –
Возможно, ваша проблема возникает из-за того, что вы выполняете привязку к интерфейсу? Взгляните на этот вопрос, может быть полезно http://stackoverflow.com/questions/327984/wpf-databinding-to-interface-and-not-actual-object-casting-possible – lena