我有一个UWP UserControl,用于显示分组的项目(带标签的),可以通过单击标签头将其展开,但也支持未标记的项目。 (类似于TreeView,其中每个项目可能在节点内也可能不在节点内)。
因此输出可能看起来像这样-标签行可以折叠或展开,并且未标记的项目显示在已标记的项目下方:
白皮书
–白皮书1.pdf
–白皮书2.pdf
技术规范
–技术规范1.doc
–技术规范2.doc
DocumentWithNoTag1.pdf
DocumentWithNoTag2.doc
该控件使用模板选择器来选择要显示的两种类型的内容之一(TaggedItemTemplate或UntaggedItemTemplate数据模板),但是我需要一组通用的VisualStateManger状态,我可以使用这两种模板从下面的代码中设置其状态。任何项目都被选中。因此,在选择绑定项目时,我需要显示可视状态“ FolderVisualState”或“ FileVisualState”。
问题是,当我运行它并转到将可视状态设置为的代码(在OnMiscItemPropertyChanged中)时,出现错误:
“ System.Runtime.InteropServices.COMException:'未检测到已安装的组件。名称为'FolderExpander'的目标对象无法解析给Setter。'”。
这是我的UserControl:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Athena.UWP.Components"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:components="using:Athena.UWP.Components"
xmlns:models="using:Athena.UWP.Models"
xmlns:Converters="using:Template10.Converters"
xmlns:primitives="using:Telerik.UI.Xaml.Controls.Primitives"
xmlns:data="using:Telerik.UI.Xaml.Controls.Data"
x:Class="Athena.UWP.Components.MiscItemView"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<Converters:StringFormatConverter x:Key="StringFormatConverter" />
<DataTemplate x:Key="SubItemDataTemplate"
x:DataType="models:BoardMiscItem">
<components:MiscItemView MiscItem="{x:Bind Mode=OneWay}"
ItemSelected="OnSubItemSelected" />
</DataTemplate>
<Thickness x:Key="ButtonContentItemMargin">0,0,8,0</Thickness>
<DataTemplate x:Key="FileButtonTemplate"
x:DataType="models:BoardMiscItem">
<Button x:Name="FileButton"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Visibility="Collapsed"
Click="OnItemClicked"
HorizontalContentAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<Border CornerRadius="45"
Height="10"
Width="10"
Margin="{StaticResource ButtonContentItemMargin}">
<Border.Background>
<SolidColorBrush Color="{x:Bind StateColour, Mode=OneWay}" />
</Border.Background>
</Border>
<TextBlock TextWrapping="Wrap"
Text="{x:Bind DisplayName, Mode=OneWay}"
Grid.Column="1"
Margin="{StaticResource ButtonContentItemMargin}" />
<TextBlock Text="{x:Bind UpdateDate, Converter={StaticResource StringFormatConverter}, ConverterParameter=\{0:dd MMM yyyy\}, Mode=OneWay}"
Grid.Column="2"
Margin="{StaticResource ButtonContentItemMargin}" />
<TextBlock Text="{x:Bind Type, Mode=OneWay}"
Grid.Column="4"
TextTrimming="CharacterEllipsis"
ToolTipService.ToolTip="{x:Bind Type, Mode=OneWay}" />
</Grid>
</Button>
</DataTemplate>
<DataTemplate x:Key="TaggedItemTemplate" x:DataType="models:BoardMiscItem">
<Grid>
<Button Content="FileButtonTemplate" DataContext="{Binding}"/>
<Controls:Expander x:Name="FolderExpander"
Header="{Binding MiscItem.Tag, Mode=OneWay}"
Visibility="Collapsed"
HorizontalContentAlignment="Stretch">
<ListView ItemsSource="{Binding SubItems, Mode=OneWay}"
HorizontalContentAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ItemTemplate="{StaticResource SubItemDataTemplate}"
ItemContainerStyle="{StaticResource StretchListViewItemStyle}"
SelectionMode="None" />
</Controls:Expander>
</Grid>
</DataTemplate>
<DataTemplate x:Key="UntaggedItemTemplate" x:DataType="models:BoardMiscItem">
<Button Content="FileButtonTemplate" DataContext="{Binding}"/>
</DataTemplate>
<components:MiscItemTemplateSelector x:Key="MiscItemTemplateSelector"
ExpanderTemplate="{StaticResource TaggedItemTemplate}"
NormalTemplate="{StaticResource UntaggedItemTemplate}" />
</UserControl.Resources>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MiscItemStateGroup">
<VisualState x:Name="NoVisualState" />
<VisualState x:Name="FileVisualState">
<VisualState.Setters>
<Setter Target="FileButton.(UIElement.Visibility)" Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FolderVisualState">
<VisualState.Setters>
<Setter Target="FolderExpander.(UIElement.Visibility)" Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Content="{Binding MiscItem}"
ContentTemplateSelector="{StaticResource MiscItemTemplateSelector}"/>
</Grid>
</UserControl>
这是背后的代码。如果单击了文件夹级别(节点)项或FileVisualState项是实际文件,则状态选择应显示FolderVisualState。
namespace MyApp.UWP.Components
{
public sealed partial class MiscItemView : UserControl
{
public DataTemplate NormalTemplate { get; set; }
public DataTemplate ExpanderTemplate { get; set; }
public MiscItemView()
{
this.InitializeComponent();
}
public static readonly DependencyProperty MiscItemProperty =
DependencyProperty.Register(nameof(MiscItem), typeof(BoardMiscItem), typeof(MiscItemView),
new PropertyMetadata(null, OnMiscItemPropertyChanged));
public BoardMiscItem MiscItem
{
get
{
return (BoardMiscItem)GetValue(MiscItemProperty);
}
set
{
SetValue(MiscItemProperty, value);
}
}
private static void OnMiscItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var view = d as MiscItemView;
BoardMiscItem miscItem = (BoardMiscItem)e.NewValue;
if (miscItem == null)
{
VisualStateManager.GoToState(view, nameof(NoVisualState), true);
}
else if (miscItem.SubItems.Any())
{
VisualStateManager.GoToState(view, nameof(FolderVisualState), true);
}
else
{
VisualStateManager.GoToState(view, nameof(FileVisualState), true);
}
}
public event RoutedEventHandler ItemSelected;
private void OnSubItemSelected(object sender, RoutedEventArgs e)
{
ItemSelected?.Invoke(sender, e);
}
private void OnItemClicked(object sender, RoutedEventArgs e)
{
ItemSelected?.Invoke(MiscItem, e);
}
}
}
我猜这是某种名称空间问题,其中XAML中的VisualState不知道如何访问正确的DataTemplate。我已经用谷歌搜索,但没有找到解决此类问题的任何答案...有人可以建议如何解决此问题吗?