There is a working TreeView and a model for it. But it does not work to drive him into the columns (or rather, 3 columns). The code is attached.

<TreeView Name="treeViewGrid" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="1"> <TreeView.ItemTemplate> <DataTemplate> <TreeViewItem ItemsSource="{Binding Children}" > <!--Item Source--> <TreeViewItem.Header> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="70"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Property}" HorizontalAlignment="Left" Grid.Column="0"> </TextBlock> <Grid Grid.Column="1" HorizontalAlignment="Left" Visibility="{Binding ServerVisible,Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}" > <Grid.ColumnDefinitions> <ColumnDefinition Width="15"></ColumnDefinition> <ColumnDefinition Width="*" ></ColumnDefinition> </Grid.ColumnDefinitions> <RadioButton IsChecked="{Binding Path=IsServerSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Visibility="{Binding Equal, Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}" Grid.Column="0"> </RadioButton> <CheckBox IsChecked="{Binding Path=IsServerSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" > <CheckBox.Style> <Style TargetType="CheckBox"> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding Equal}" Value="True"/> <Condition Binding="{Binding LocalVisible}" Value="False"/> </MultiDataTrigger.Conditions> <Setter Property="Visibility" Value="Visible"/> </MultiDataTrigger> </Style.Triggers> </Style> </CheckBox.Style> </CheckBox> <TextBlock HorizontalAlignment="Left" Text="{Binding Server}" Grid.Column="1"> </TextBlock> </Grid> <Grid Grid.Column="2" HorizontalAlignment="Left" Visibility="{Binding LocalVisible,Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="15"></ColumnDefinition> <ColumnDefinition Width="*" ></ColumnDefinition> </Grid.ColumnDefinitions> <RadioButton IsChecked="{Binding Path=IsLocalSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Visibility="{Binding Equal, Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}" IsEnabled="{Binding Path=!IsServerSelected}" Grid.Column="0"> </RadioButton> <CheckBox IsChecked="{Binding Path=IsLocalSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" > <CheckBox.Style> <Style TargetType="CheckBox"> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding Equal}" Value="True"/> <Condition Binding="{Binding ServerVisible}" Value="False"/> </MultiDataTrigger.Conditions> <Setter Property="Visibility" Value="Visible"/> </MultiDataTrigger> </Style.Triggers> </Style> </CheckBox.Style> </CheckBox> <TextBlock HorizontalAlignment="Left" Text="{Binding Local}" Grid.Column="1"> </TextBlock> </Grid> </Grid> </TreeViewItem.Header> <TreeViewItem.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="70"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> </Grid.ColumnDefinitions> <TextBlock Text="{Binding ChildProperty}" HorizontalAlignment="Left" Grid.Column="0"> </TextBlock> <Grid Grid.Column="1" Visibility="{Binding ChildServerVisible,Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="15"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <RadioButton IsChecked="{Binding Path=IsServerSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Visibility="{Binding ChildEqual, Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}" Grid.Column="0"> </RadioButton> <CheckBox IsChecked="{Binding Path=IsServerSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" > <CheckBox.Style> <Style TargetType="CheckBox"> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding ChildEqual}" Value="True"/> <Condition Binding="{Binding ChildLocalVisible}" Value="False"/> </MultiDataTrigger.Conditions> <Setter Property="Visibility" Value="Visible"/> </MultiDataTrigger> </Style.Triggers> </Style> </CheckBox.Style> </CheckBox> <TextBlock HorizontalAlignment="Left" Text="{Binding ChildServer}" Grid.Column="1"> </TextBlock> </Grid> <Grid Grid.Column="2" Visibility="{Binding ChildLocalVisible,Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="15"></ColumnDefinition> <ColumnDefinition Width="*" ></ColumnDefinition> </Grid.ColumnDefinitions> <RadioButton IsChecked="{Binding Path=IsLocalSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Visibility="{Binding ChildEqual, Converter={StaticResource BoolToVisibility},FallbackValue=Hidden}" Grid.Column="0" IsEnabled="{Binding Path=!IsServerSelected}" > </RadioButton> <CheckBox IsChecked="{Binding Path=IsServerSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" > <CheckBox.Style> <Style TargetType="CheckBox"> <Setter Property="Visibility" Value="Collapsed"/> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding ChildEqual}" Value="True"/> <Condition Binding="{Binding ChildServerVisible}" Value="False"/> </MultiDataTrigger.Conditions> <Setter Property="Visibility" Value="Visible"/> </MultiDataTrigger> </Style.Triggers> </Style> </CheckBox.Style> </CheckBox> <TextBlock HorizontalAlignment="Left" Text="{Binding ChildLocal}" Grid.Column="1"> </TextBlock> </Grid> </Grid> </DataTemplate> </TreeViewItem.ItemTemplate> </TreeViewItem> </DataTemplate> </TreeView.ItemTemplate> </TreeView> 

And here is the model:

 public class MergeTreeView : INotifyPropertyChanged { public string Property { get; set; } public string Server { get; set; } public string Local { get; set; } public bool Equal { get; set; } public bool ServerVisible { get; set; } public bool LocalVisible { get; set; } public List<Merge> Children { get; set; } bool IsComplex { get { return Children != null && Children.Any(); } } public MergeTreeView(string PropName, IPropertyRepresentation fromServer, IPropertyRepresentation local, IPropertyProvider provider) { this.Property = PropName; this.Server = fromServer == null ? " " : fromServer.GetStringValue; this.Local = local == null ? " " : local.GetStringValue; this.Equal = provider.Compare(fromServer, local); Children = Controller.GetDataForChild(fromServer == null ? null : fromServer.Children, local == null ? null : local.Children, provider); this.ServerVisible = fromServer != null; this.LocalVisible = local != null; mSelectedSide = ServerVisible ? SelectedSide.ServerSelected : SelectedSide.LocalSelected; } enum SelectedSide { LocalSelected, ServerSelected } private SelectedSide mSelectedSide; public bool IsLocalSelected { get { return mSelectedSide == SelectedSide.LocalSelected; } set { if (value == IsLocalSelected) return; mSelectedSide = value ? SelectedSide.LocalSelected : SelectedSide.ServerSelected; OnPropertyChanged("IsLocalSelected"); OnPropertyChanged("IsServerSelected"); } } public bool IsServerSelected { get { return mSelectedSide == SelectedSide.ServerSelected; } set { if (value == IsServerSelected) return; mSelectedSide = value ? SelectedSide.ServerSelected : SelectedSide.LocalSelected; OnPropertyChanged("IsLocalSelected"); OnPropertyChanged("IsServerSelected"); } } private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; } 

    1 answer 1

    See an example from MS here: https://msdn.microsoft.com/library/ms771523(v=vs.90).aspx