3

理解できない次の動作に遭遇しています。次のように正しく表示されるデータがありTreeViewます。

スポーツ
  > 野球
    > アパレル
    > 設備
        グローブ
        バット
  > サッカー
    > ヘルメット
  > サッカー

ただし、任意のノードをクリックすると、基になるノード データはその最初の子のデータになります。

    クリックされたノードの実際のデータ
-------------------------------------------
    スポーツ 野球
    野球アパレル
    フットボール用ヘルメット
    バットヌル

Web や書籍で多くの例を見てきましたが、問題を特定できません。とてもシンプルだと思います。

編集デバッガーで各ノードを視覚的に検査し、TreeView のすべてのコントロールの型と値を実際に表示する C# 2010 の Mathew MacDonald の Pro WPF の便利な小さなコード スニペットを使用しました。

編集最初のコードを、問題を再現する実際の完全なアプリケーションに置き換えました。これは私が思いつく最も単純な例です。

コード (無関係なセクションを削除):

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:this="clr-namespace:WpfApplication1"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <this:MainWindowViewModel x:Key="ViewModel:MainWindow"></this:MainWindowViewModel>
    </Application.Resources>
</Application>

-

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{StaticResource ViewModel:MainWindow}">
    <TreeView x:Name="theTree" ItemsSource="{Binding Path=OrgChart}"
              MouseUp="theTree_MouseUp">
        <TreeView.Resources>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=Subordinates}" DataType="{x:Type this:OrgChartNodeViewModel}">
                <TextBlock Text="{Binding Path=Position.Title}"></TextBlock>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>
</Window>

-

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void theTree_MouseUp(object sender, MouseButtonEventArgs e)
    {
        Stack<DependencyObject> stack = new Stack<DependencyObject>();
        var it = e.OriginalSource as DependencyObject;
        while (it != null)
        {
            it = VisualTreeHelper.GetParent(it);
            stack.Push(it);
        }

        int level = 0;
        while (stack.Any())
        {
            Debug.Write("".PadLeft(level++));
            it = stack.Pop();
            if (it is TreeViewItem)
            {
                var item = it as TreeViewItem;
                OrgChartNodeViewModel vm = ((OrgChartNodeViewModel)((TreeViewItem)it).Items.CurrentItem);
                if (vm != null)
                    Debug.WriteLine(vm.Position.Title);
            }
            else
            {
                Debug.WriteLine(it);
            }
        }
    }
}

-

public class MainWindowViewModel
{
    public List<OrgChartNodeViewModel> OrgChart { get; set; }

    public MainWindowViewModel()
    {
        Position ceo = new Position { Title = "CEO" };
        Position vp = new Position { Title = "VP" };
        Position boss = new Position { Title = "Boss" };
        Position worker = new Position { Title = "Worker" };

        OrgChartNodeViewModel root;
        OrgChartNodeViewModel node = new OrgChartNodeViewModel { Position = ceo };
        OrgChartNodeViewModel child = new OrgChartNodeViewModel { Position = vp };
        root = node;
        node.Subordinates.Add(child);
        node = child;
        child = new OrgChartNodeViewModel { Position = boss };
        node.Subordinates.Add(child);
        node = child;
        child = new OrgChartNodeViewModel { Position = worker };
        node.Subordinates.Add(child);

        OrgChart = new List<OrgChartNodeViewModel> { root };
    }
}

-

public class OrgChartNodeViewModel
{
    public Position Position { get; set; }
    public List<OrgChartNodeViewModel> Subordinates { get; set; }

    public OrgChartNodeViewModel()
    {
        Subordinates = new List<OrgChartNodeViewModel>();
    }
}

-

public class Position
{
    public string Title { get; set; }
}

これが私のマシンの出力です...

ここに画像の説明を入力

4

1 に答える 1

3

切り替えてみる

OrgChartNodeViewModel vm = ((OrgChartNodeViewModel)((TreeViewItem)it).Items.CurrentItem);

OrgChartNodeViewModel vm = ((OrgChartNodeViewModel)viewItem.DataContext);

while ループでは、その子を指すのTreeViewItem.DataContextではなく、 が必要です(最初に展開されるまでは 1 つだけ存在します)。Items.CurrentItemしたがって、CEO ではなく VP が表示されているのはそのためです。

関数全体を次のようなものに切り替えます。

private void theTree_MouseUp(object sender, MouseButtonEventArgs e) {
  var clickedItem = e.OriginalSource as FrameworkElement;
  if (clickedItem == null)
    return;
  var chartNode = clickedItem.DataContext as OrgChartNodeViewModel;
  if (chartNode != null)
    Debug.WriteLine(chartNode.Position.Title);
}

Visual-Tree を反復処理してTreeViewItem. DataContextxaml セットアップで継承されるため、冗長な作業を省くために使用することもできます。

于 2013-06-28T03:33:05.340 に答える