TreeView.ItemTemplate 分层数据模板中的数据在切换所选树项时被擦除



我有以下代码:

Template.XAML

<Style TargetType="{x:Type HeaderedContentControl}">
<Setter Property="Header">
<Setter.Value>
<ContentControl  Foreground="Red" 
FontFamily="Segoe UI" 
Margin="0,0,0,20" 
Content="{Binding Tag, RelativeSource={RelativeSource AncestorType=HeaderedContentControl}}" 
HorizontalAlignment="Center" 
VerticalAlignment="Center" />
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type local:ViewModel}">
<HeaderedContentControl  xmlns:sys="clr-namespace:System;assembly=mscorlib"
Tag="{Binding Header}"
Background="SteelBlue"
BorderBrush="DarkSlateBlue">
</HeaderedContentControl>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModel2}">
<HeaderedContentControl  xmlns:sys="clr-namespace:System;assembly=mscorlib"
Tag="{Binding Header}"
Background="SteelBlue"
BorderBrush="DarkSlateBlue">
</HeaderedContentControl>
</DataTemplate>

Windows.XAML:

<Window.DataContext>
<local:WindowsVM x:Name="viewModel"/>
</Window.DataContext>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Templates.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel Orientation="Horizontal">
<TreeView SelectedItemChanged="TreeView_SelectedItemChanged" ItemsSource="{Binding AllContents}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate>
<Label Content="{Binding Header}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<StackPanel Orientation="Vertical">
<ContentControl Content="{Binding SelectedItem}" />
</StackPanel>
</StackPanel>

Windows.XAML.cs

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
viewModel.SelectedItem = (ViewModel)e.NewValue;
}
}

ViewModel.cs

public class WindowsVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public WindowsVM()
{
AllContents = new ObservableCollection<ViewModel>();
AllContents.Add(new ViewModel("Item 1"));
AllContents.Add(new ViewModel2("Item 2")); //using ViewModel("Item 2") will show the Header as it should
SelectedItem = AllContents.First();
}
private ViewModel _selectedItem;
public ViewModel SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem)));
}
}
private ObservableCollection<ViewModel> _allContents;
public ObservableCollection<ViewModel> AllContents
{
get { return _allContents; }
set
{
_allContents = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(AllContents)));
}
}
}
public  class ViewModel:INotifyPropertyChanged
{
private string _header;
public event PropertyChangedEventHandler PropertyChanged;
public string Header
{
get { return _header; }
set
{
_header = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Header)));
}
}
public ViewModel(string header)
{
Header = header;
}
}

public class ViewModel2 : ViewModel
{
public ViewModel2(string header) : base(header)
{
}
}

如果运行应用程序,"项目 1"将显示为所选项目的标题,它应该显示。

如果您单击第二个树节点,我希望"项目 2"显示为所选项目的标题,但事实并非如此。

这是有趣的部分,如果对于"项目 2",它是类型ViewModel而不是ViewModel2,则将显示"项目 2"标题。怎么会这样?这是 WPFtreeview错误吗?

我也欢迎本着 MVVM 模型的精神进行解决方法。

应将HeaderedContentControlHeader属性绑定到Header源属性,然后在HeaderedContentControl样式中定义HeaderTemplate

如果实现如下Templates.xaml,则示例将按预期工作:

<Style TargetType="{x:Type HeaderedContentControl}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Label Foreground="Red" 
FontFamily="Segoe UI" 
Margin="0,0,0,20" 
Content="{Binding}" 
HorizontalAlignment="Center" 
VerticalAlignment="Center" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type local:ViewModel}">
<HeaderedContentControl Header="{Binding Header}"
Background="SteelBlue"
BorderBrush="DarkSlateBlue">
</HeaderedContentControl>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModel2}">
<HeaderedContentControl Header="{Binding Header}"
Background="SteelBlue"
BorderBrush="DarkSlateBlue">
</HeaderedContentControl>
</DataTemplate>

最新更新