我的任务是在我们的WPF应用程序中实现一个类似于MDI的接口。
我创建了这个简单的类作为所有视图的基础:
public class BaseView : UserControl, INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private ViewType _type = ViewType.Null;
private string _tabTitle = string.Empty;
private bool _isSelected = false;
public ViewType Type { get => _type; set { _type = value; OnPropertyChanged(); } }
public string TabTitle { get => _tabTitle; set { _tabTitle = value; OnPropertyChanged(); } }
public bool IsSelected { get => _isSelected; set { _isSelected = value; OnPropertyChanged(); } }
}
接下来,我创建了几个测试视图,它们都是这样开始的:<local:BaseView...
在主窗口中,有两个控件:ItemsControl(用于显示已打开视图的列表)和ContentControl(用于显示所选视图)。
我将所有打开的视图存储在ObservableCollection中:ObservableCollection<BaseView>...
。我想将它们显示为列表,因此创建了ItemsControl:
<ItemsControl x:Name="mainItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Padding="2" Margin="2" Tag="{Binding Type}">
<TextBlock Text="{Binding TabTitle}" Foreground="White"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
当我设置ItemsControl的源代码(mainItemsControl.ItemsSource = openedViews;
)并启动应用程序时,ItemsControl显示的是每个视图的内容,而不是ItemTemplate(带TextBlock的边框)。我做错了什么?
1条答案
按热度按时间cygmwpex1#
如果我没理解错的话,openedViews集合是由BaseView组成的,那么BaseView就是一个UIElement。
但数据模板用于呈现非UIElements。
如果Content接收到UIElement,则直接按原样呈现。
一种可能的变体解决方案。
您需要从BaseView中删除INotifyPropertyChanged接口。请使用INotifyPropertyChanged的实现为BaseView创建数据源。
在BaseView中为此源创建DependencyProperty。
为openedViews集合创建一个简单的帮助器容器。
如下所示(伪代码):