XamDataTree のノードを表示・非表示にしたい場合、コードビハインドで各ノードを操作する必要はありません。XamDataTreeNodeControlVisibility プロパティをデータ上の可視フラグにバインドすることで、データバインドだけでノードの表示・非表示を制御できます。

XamDataTree の設定

まず、ノードの表示・非表示を切り替えたい対象データに、可視フラグを表すプロパティを用意します。

class NodeData : INotifyPropertyChanged
{
    public string? Name { get; set; }
    public ObservableCollection<NodeData>? Children { get; set; }

    private bool isVisible;
    public bool IsVisible
    {
        get { return isVisible; }
        set { isVisible = value; NotifyPropertyChanged("IsVisible"); }
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    public void NotifyPropertyChanged(string info) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}

次に、XamDataTree 側で NodeLayoutTargetTypeName にこのデータ型を指定し、NodeStyle に、後述する Visibility バインドを含むスタイルを割り当てます。

<ig:XamDataTree x:Name="xamDataTree1" ItemsSource="{Binding TreeSource}" NodeLineVisibility="Visible">
    <ig:XamDataTree.GlobalNodeLayouts>
        <ig:NodeLayout
            Key="layout"
            DisplayMemberPath="Name"
            TargetTypeName="NodeData"
            NodeStyle="{StaticResource NodeStyle}"/>
    </ig:XamDataTree.GlobalNodeLayouts>
</ig:XamDataTree>

Visibility プロパティのバインド

XamDataTreeNodeControl を対象とした NodeStyle の中で、Visibility プロパティに対して Setter を追加し、ノードが保持するデータの IsVisible プロパティに BoolToVisibilityConverter を介してバインドします。これにより、データ側のフラグを切り替えるだけで、対応するノードの表示・非表示が切り替わります。

<igPrim:BoolToVisibilityConverter x:Key="BoolToVis"/>

<Style TargetType="{x:Type ig:XamDataTreeNodeControl}" x:Key="NodeStyle">
    <Setter Property="Visibility" Value="{Binding Node.Data.IsVisible, Converter={StaticResource BoolToVis}}" />
    ...
</Style>

ただし、ノードを非表示にすると、既定のノード線のままでは、実際に表示されている最下位のノードの線の終端(L字型の線)が正しい位置に表示されないことがあります。これに対応するため、同じ NodeStyleTemplate を上書きしています。

この Template を上書きする際は、次に示す XamDataTreeNodeControl の既定のスタイル定義をベースにしてください: generic.xaml(wpf-resources)

具体的には、上記の既定テンプレートに含まれる NodeLineTerminatorVisibility を、後続の兄弟ノードに表示中のノードがあるかどうかを判定するカスタムコンバータにバインドし直します。

<igPrimDT:NodeLineTerminator Grid.Column="1" x:Name="LineTerminator" Node="{Binding Node, RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Node, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource hideLastNodeLine}}"/>

<Grid Grid.Column="1" Visibility="{Binding Node, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource showLastNodeLine}}">
    <Grid.RowDefinitions>
        <RowDefinition Height="0.5*"/>
        <RowDefinition Height="0.5*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.5*"/>
        <ColumnDefinition Width="0.5*"/>
    </Grid.ColumnDefinitions>
    <Rectangle Width="1" Fill="#FFA3AEB9" HorizontalAlignment="Left" Grid.Column="1"/>
    <Rectangle VerticalAlignment="Top" Height="1" Fill="#FFA3AEB9" Grid.Row="1" Grid.Column="1"/>
</Grid>

hideLastNodeLine は「後続の兄弟ノードに表示中のノードがない場合」に既定のノード線を隠し、showLastNodeLine はその代わりに、子ノードを持たないノードのために調整済みの線(縦線+横線のみの図形)を表示します。

実行結果

上記の設定により、IsVisiblefalse のノードはツリー上に表示されなくなり、非表示ノードが挟まっていても、表示されているノード同士のノード線が途切れることなく正しく描画されます。

Tagged:

製品について

Ultimate UI for WPF