我正在构建一个插件系统,其中每个插件都有自己的状态栏,包含不同的区域。因此,插件#1可以有一个2 x 200像素区域的状态栏,而插件#2可以只有一个400像素区域。
我在WPF/MVVM
和应用程序的视图模型中构建这个,当我在插件之间切换时,插件的StatusBar
被加载。
我有一个可观察的状态栏集合,我加载到:
ObservableCollection<StatusBar> StatusBars
{
get;
set;
}
然后我有一个函数只是检索状态栏的集合为该插件。
被加载的类看起来像这样:
public class StatusBar : ObservableObject
{
public string Name { get; set; }
public int Width { get; set; }
public StatusBarAreaType Type { get; set; }
string _message;
public string Message
{
get
{
return _message;
}
set
{
if (_message != value)
{
_message = value;
OnPropertyChanged();
}
}
}
}
我的问题是,我不能得到XAML支持我加载集合,并显示每个StatusBar
作为自己的区域。我如何尝试这样做的一个简化版本看起来像这样:
<StatusBar VerticalAlignment="Bottom" Height="25" ItemsSource="{Binding StatusBars}" ItemTemplate="{DynamicResource StatusBarTemplate}">
<StatusBar.Resources>
<DataTemplate x:Key="StatusBarTemplate">
<TextBlock Text="{Binding Message}"></TextBlock>
</DataTemplate>
</StatusBar.Resources>
</StatusBar>
(我已经尝试了StatusBarItem
的东西,ItemsControl
模板,使用网格内部代替等)
我如何实现基于StatusBar类的不同区域组成的StatusBar
的目标?
我现在可以解决这个问题了,这是我的XAML:
<UserControl x:Class="MyCompany.View.StatusBarControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewModel="clr-namespace:MyCompany.ViewModel"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding StatusBar,Source={StaticResource Locator}}">
<UserControl.Resources>
<DataTemplate x:Key="SimpleTextDataTemplate">
<StatusBarItem Width="{Binding Width}" Margin="0,5,0,0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Message}"></TextBlock>
</StackPanel>
</StatusBarItem>
</DataTemplate>
<DataTemplate x:Key="ErrorDataTemplate">
<StatusBarItem Width="{Binding Width}" Margin="0,5,0,0">
<TextBlock Text="{Binding Message}"></TextBlock>
</StatusBarItem>
</DataTemplate>
<DataTemplate x:Key="ProgressBarDataTemplate">
<StatusBarItem Width="{Binding Width}" Margin="0,10,0,0">
<ProgressBar Width="{Binding Width}" Height="{Binding ElementName=theStatusBar,Path=Height}" Value="{Binding Message}"></ProgressBar>
</StatusBarItem>
</DataTemplate>
</UserControl.Resources>
<Grid>
<StatusBar x:Name="theStatusBar" VerticalAlignment="Bottom" Background="#d0d2d6" Height="30"
ItemsSource="{Binding StatusBars}">
<StatusBar.ItemTemplateSelector>
<viewModel:StatusBarRegionSelector SimpleTextTemplate="{StaticResource SimpleTextDataTemplate}"
ErrorTemplate="{StaticResource ErrorDataTemplate}"
ProgressBarTemplate="{StaticResource ProgressBarDataTemplate}" />
</StatusBar.ItemTemplateSelector>
</StatusBar>
</Grid>
</UserControl>
和后面的代码:
public class StatusBarRegionSelector : DataTemplateSelector
{
public DataTemplate SimpleTextTemplate { get; set; }
public DataTemplate ErrorTemplate { get; set; }
public DataTemplate ProgressBarTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var statusBar = (StatusBar) item;
if (statusBar != null)
switch (statusBar.Type)
{
case StatusBarAreaType.SimpleText:
return SimpleTextTemplate;
break;
case StatusBarAreaType.Error:
return ErrorTemplate;
break;
case StatusBarAreaType.ProgressBar:
return ProgressBarTemplate;
break;
default:
throw new ArgumentOutOfRangeException();
}
return SimpleTextTemplate;
}
}
现在剩下的唯一问题是在每个项目之间添加一个分隔符,只是添加一个分隔符现在不工作,因为某些原因,它不会显示,无论我把它放在哪里。