WPF:BindingExpression返回null,尽管source属性具有值

时间:2016-01-22 09:44:02

标签: c# wpf data-binding datatemplate itemscontrol

我遇到了一个使用ItemsControl的ItemTemplate的非常奇怪的行为。一些BindingExperssions返回null,尽管是DataContext。

以下是有问题的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中的Content属性被检索到。我期望的值确实显示在屏幕上。但是,Horizo​​ntalTextAlignment在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.Horizo​​ntalAlignment)和一个值(我默认设置一个,这是一个枚举,因此有&#34;没有机会&#34;为null )。

我还使用IValueConverter进行了一次测试。在Binding中指定Path时,转换器确实会收到null。当没有路径时,它接收整个对象并对其进行调试,并且它具有该属性的值。感觉好像WPF中有一些错误,但我真的希望我错了。

有谁知道为什么以及如何发生这种情况?也许我该如何解决这个问题?

编辑(根据要求): 这是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; }
}

来自ViewModel的ItemsSource属性:

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)
    {
    }
}

和IndexCell:

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)
    {
    }
}

非常感谢!

1 个答案:

答案 0 :(得分:0)

我可以创建例外的唯一方法就是这样

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

public class IndexCell : ICell
{
   public string Content { get; set; }
   public Color TextColor { get; set; }
   public Color BackgroundColor { get; set; }
   public double FontSize { get; set; }
   public FontWeight FontWeight { get; set; }
   public TextWrapping TextWrapping { get; set; }
   public HorizontalAlignment? HorizontalTextAlignment { get; set; }
   public VerticalAlignment VerticalTextAlignment { get; set; }
   public string ToolTip { get; set; }
}

因此请确保您在IndexCell中使用的类型。某种类型可以包含null的类型正在达到绑定。

我的例外:

System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='<null>' BindingExpression:Path=HorizontalTextAlignment; DataItem='IndexCell' (HashCode=55786324); target element is 'TextBlock' (Name=''); target property is 'HorizontalAlignment' (type 'HorizontalAlignment')

查看enum属性可以返回枚举中指定的其他值。例如尝试将任何整数值强制转换为任何枚举。

 public HorizontalAlignment HorizontalTextAlignment
    {
        get
        {
            return (HorizontalAlignment)100;
        }            
    }

这将正常工作,您将在运行时遇到绑定错误(与您的相同)。我不知道你的班级等级,所以不能肯定地说。但是你在 GetProperty(...)方法中使用泛型,这样就可以返回null。你可以肯定知道的唯一方法就是调试它是如何以&lt;空&GT;