WPF数据绑定错误 - System.Windows.Data错误:40

时间:2014-04-01 20:35:25

标签: c# wpf xaml

我一直在敲桌子试图找出为什么我继续得到这个WPF XAML数据绑定错误。

System.Windows.Data错误:40:BindingExpression路径错误:在'object'''TreeViewItem'(Name ='')'上找不到'Source'属性。空值 System.Windows.Data错误:40:BindingExpression路径错误:'对象'''TreeViewItem'(Name ='')'上找不到'Source'属性。空

我已将其追溯到XAML代码中的这一行

   <local:GameLogSourceTree x:Name="_gamesSourcesTree" TreeNodeStyle="{StaticResource GenericFolders}" TreeStyle="{StaticResource GenericTreeStyle}" NodeSortDescriptions="{StaticResource AscendingNames}"/> 

指的是xaml代码DataTriggers中的“Source”属性,如果这是正确的。任何帮助都很受欢迎。

以下是XAML代码&amp;它背后的C#代码

 XAML Code 

    <UserControl x:Class="Test.UI.Noc"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         mc:Ignorable="d" 
         xmlns:local="clr-namespace:Test.UI"
         xmlns:cm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
         xmlns:Logs="clr-namespace:Test.Logs;assembly=Test.Logs">
 <UserControl.Resources>
    <local:SourceStateConverter x:Key="gamesourceStateConverter"/>
    <DataTemplate x:Key="GameNodeTemplate" DataType="{x:Type local:GameLogSourceNode}">
        <StackPanel x:Name="GroupPanel" Orientation="Horizontal" Margin="0,2,0,2">
            <Image x:Name="Folder"   Source="/Test.UI;component/Test.UI/Images/GameRoot.png"/>
            <TextBlock x:Name="CategoryName" Margin="2,0,0,0" Text="{Binding Path=Source.(Logs:IGameLogsSource.Name)}"/>
        </StackPanel>
        <DataTemplate.Triggers>
            <DataTrigger Value="True" Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}}">
                <Setter TargetName="CategoryName" Property="TextBlock.FontWeight" Value="Bold"/>
                <Setter Property="UIElement.Effect">
                    <Setter.Value>
                        <DropShadowEffect ShadowDepth="2" BlurRadius="10" RenderingBias="Quality"/>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
            <DataTrigger Value="-1" Binding="{Binding Path=Source, Converter={StaticResource gamesourceStateConverter}}">
                <Setter TargetName="Folder" Property="Image.Source" Value="/Test.UI;component/Test.UI/Images/Process.png"/>
            </DataTrigger>
            <DataTrigger Value="0" Binding="{Binding Path=Source, Converter={StaticResource gamesourceStateConverter}}">
                <Setter TargetName="Folder" Property="Image.Source" Value="/Test.UI;component/Test.UI/Images/Process.png"/>
            </DataTrigger>
            <DataTrigger Value="1" Binding="{Binding Path=Source, Converter={StaticResource gamesourceStateConverter}}">
                <Setter TargetName="Folder" Property="Image.Source"
              Value="/Test.UI;component/Test.UI/Images/GameStopping.png"/>
            </DataTrigger>
            <DataTrigger Value="2" Binding="{Binding Path=Source, Converter={StaticResource gamesourceStateConverter}}">
                <Setter TargetName="Folder" Property="Image.Source"
              Value="/Test.UI;component/Test.UI/Images/GameStopped.png"/>
            </DataTrigger>
            <DataTrigger Value="Games" Binding="{Binding Path=Source.(Logs:IGameLogsSource.Name)}">
                <Setter TargetName="Folder" Property="Image.Source"
              Value="/Test.UI;component/Test.UI/Images/GameRoot.png"/>
            </DataTrigger>
            <DataTrigger Value="Common" Binding="{Binding Path=Source.(Logs:IGameLogsSource.Name)}">
                <Setter TargetName="Folder" Property="Image.Source"
              Value="/Test.UI;component/Test.UI/Images/NocRoot.png"/>
            </DataTrigger> 
        </DataTemplate.Triggers>
    </DataTemplate>
    <Style x:Key="GenericFolders" TargetType="{x:Type TreeViewItem}">
        <Style.Resources>
            <Brush x:Key="{x:Static SystemColors.HighlightBrushKey}">Transparent</Brush>
            <Brush x:Key="{x:Static SystemColors.ControlBrushKey}">Transparent</Brush>
            <Brush x:Key="{x:Static SystemColors.ControlTextColorKey}">Black</Brush>
        </Style.Resources>
        <Setter Property="HeaderTemplate" Value="{StaticResource GameNodeTemplate}"/>
    </Style>
    <Style x:Key="GenericTreeStyle" TargetType="{x:Type TreeView}">
        <Setter Property="Background">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                    <GradientStop Color="#FFF" Offset="0.0"/>
                    <GradientStop Color="#AAA" Offset="1.0"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderThickness" Value="4"/>
        <Setter Property="BorderBrush" Value="#FFA6AAAB"/>
    </Style>
    <cm:SortDescriptionCollection x:Key="AscendingNames">
        <cm:SortDescription PropertyName="Source.(Logs:IGameLogsSource.Name)" Direction="Ascending"/>
    </cm:SortDescriptionCollection>
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="TextWrapping" Value="Wrap"/>
    </Style>
</UserControl.Resources>
<Grid x:Name="RootGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="auto" MinWidth="175"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <local:GameLogSourceTree x:Name="_gamesSourcesTree" TreeNodeStyle="{StaticResource GenericFolders}" TreeStyle="{StaticResource GenericTreeStyle}" NodeSortDescriptions="{StaticResource AscendingNames}"/>
    <GridSplitter Grid.Column="0" HorizontalAlignment="Right" Width="2"/>
    <local:LogControl x:Name="_gamesLogControl" Grid.Column="1"/>
</Grid>

下面是C#背后。

// C# code 

 namespace Test.UI
 {
public partial class Noc : ILogListener
{
    private readonly Dictionary<Guid, Tuple<LogMessageCollection, GameLogSourceNode>> _logInfo = new Dictionary<Guid, Tuple<LogMessageCollection, GameLogSourceNode>>();


    public LogControl LogControl
    {
        get
        {
            return _gamesLogControl;
        }
    }


    public Noc()
    {
        InitializeComponent();
        _logInfo.Add(_gamesSourcesTree.GameRootNode.Source.Id, new Tuple<LogMessageCollection, GameLogSourceNode>(new LogMessageCollection(), _gamesSourcesTree.GameRootNode));
        _logInfo.Add(_gamesSourcesTree.CoreRootNode.Source.Id, new Tuple<LogMessageCollection, GameLogSourceNode>(new LogMessageCollection(), _gamesSourcesTree.CoreRootNode));
        _gamesSourcesTree.SelectedItem = _gamesSourcesTree.GameRootNode;
        _gamesSourcesTree.NodeAdded += OnSourcesTreeNodeAdded;
        _gamesSourcesTree.NodeRemoved += OnSourcesTreeNodeRemoved;
    }



    private void AddNodeIfNeeded(IGameLogsSource source)
    {
        IGameLogsSource i;
        GameLogSourceNode item2;
        if (_logInfo.ContainsKey(source.Id))
        {
            return;
        }
        var logSources = new Stack<IGameLogsSource>();
        logSources.Push(source);
        for (i = source.Parent; i != null && !_logInfo.ContainsKey(i.Id); i = i.Parent)
        {
            logSources.Push(i);
        }
        if (i != null)
        {
            item2 = _logInfo[i.Id].Item2;
        }
        else
        {
            i = logSources.Peek();
            item2 = (i is Game ? _gamesSourcesTree.GameRootNode : _gamesSourcesTree.CoreRootNode);
        }
        foreach (var logSource in logSources)
        {
            var tuple = _logInfo.TryGetValue(logSource.Id);
            if (tuple != null)
            {
                item2 = tuple.Item2;
            }
            else
            {
                var logSourceNode = new GameLogSourceNode(logSource, _gamesSourcesTree);
                item2.ChildNodes.Add(logSourceNode);
                item2 = logSourceNode;
            }
        }
    }



    public void Load(SettingsStorage storage)
    {
        storage.SetValue("LogControl", _gamesLogControl.Save());
    }

    private void OnSelectedItemChanged(object sender, RoutedTreeItemEventArgs<GameLogSourceNode> e)
    {
        _gamesLogControl.Messages = (e.NewItem != null ? _logInfo[e.NewItem.Source.Id].Item1 : new LogMessageCollection());
    }

    private void OnSourcesTreeNodeAdded(GameLogSourceNode node)
    {
        _logInfo.Add(node.Source.Id, new Tuple<LogMessageCollection, GameLogSourceNode>(new LogMessageCollection(), node));
    }

    private void OnSourcesTreeNodeRemoved(GameLogSourceNode node)
    {
        foreach (var childNode in node.ChildNodes)
        {
            OnSourcesTreeNodeRemoved(childNode);
        }
        _logInfo.Remove(node.Source.Id);
    }

    public void Save(SettingsStorage storage)
    {
        var value = storage.GetValue<SettingsStorage>("LogControl");
        if (value != null)
        {
            ((IPersistable)_gamesLogControl).Load(value);
        }
    }



    public virtual void WriteMessage(LogMessage message)
    {
        if (message == null)
        {
            throw new ArgumentNullException("message");
        }
        WriteMessages(message.Source, new[] { message });
    }

    public virtual void WriteMessages(IEnumerable<LogMessage> messages)
    {
        if (messages == null)
        {
            throw new ArgumentNullException("messages");
        }
        (
            from m in messages
            group m by m.Source).ForEach<IGrouping<IGameLogsSource, LogMessage>>(g => WriteMessages(g.Key, g));
    }

    private void WriteMessages(IGameLogsSource source, IEnumerable<LogMessage> messages)
    {
        AddNodeIfNeeded(source);
        for (var i = _logInfo[source.Id].Item2; i != null; i = i.ParentNode)
        {
            var item1 = _logInfo[i.Source.Id].Item1;
            item1.AddRange(messages);
            if (item1.Count > 2 * _gamesLogControl.MaxItemsCount && _gamesLogControl.MaxItemsCount > 0)
            {
                item1.RemoveRange(0, item1.Count - _gamesLogControl.MaxItemsCount);
            }
        }
    }
}
  }

1 个答案:

答案 0 :(得分:0)

您将实际数据绑定到树的哪个位置?您需要设置树的ItemSource属性。既然你使用的是代码隐藏,我猜测它应该是这样的:

_gamesSourcesTree.ItemsSource = _logInfo;