我制作了一个UWP自定义模板控件,其中包含一个ICommandBarElement集合,非常类似于标准的CommandBar控件。问题是,只要我单击CommandBar实现中包含的任何AppBarButton,就会发生未处理的异常:“不支持此类接口”。
有些事情我必须做错,但我看不到它。以下是自定义控件的代码:
public sealed class MyCommandBarControl : ContentControl
{
public MyCommandBarControl()
{
this.DefaultStyleKey = typeof(MyCommandBarControl);
this.PrimaryCommands = new ObservableCollection<ICommandBarElement>();
}
public ObservableCollection<ICommandBarElement> PrimaryCommands
{
get { return (ObservableCollection<ICommandBarElement>)GetValue(PrimaryCommandsProperty); }
set { SetValue(PrimaryCommandsProperty, value); }
}
/// <summary>
/// PrimaryCommands Dependency Property
/// </summary>
public static readonly DependencyProperty PrimaryCommandsProperty =
DependencyProperty.Register(
"PrimaryCommands",
typeof(ObservableCollection<ICommandBarElement>),
typeof(MainPage),
new PropertyMetadata(null, null));
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var primaryItemsControl = GetTemplateChild("PrimaryItemsControl") as ItemsControl;
primaryItemsControl.ItemsSource = this.PrimaryCommands;
}
}
以及相关的风格:
<Style TargetType="local:MyCommandBarControl" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyCommandBarControl">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}">
<Grid x:Name="ContentRoot"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Margin="{TemplateBinding Padding}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
Opacity="{TemplateBinding Opacity}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ContentControl
x:Name="ContentControl"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
IsTabStop="False"
Margin="10, 0, 0, 0"/>
<ItemsControl
x:Name="PrimaryItemsControl"
IsTabStop="False"
Grid.Column="1"
Margin="10, 0, 0, 0"
HorizontalAlignment="Right"
HorizontalContentAlignment="Right">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我制作了一个small project you can download来重现问题。任何有助于解决此异常的帮助都将受到赞赏。
答案 0 :(得分:1)
为什么不从CommandBar控件继承,也不需要自己管理PrimaryCommands。
因此,只需将代码更改为以下内容即可解决问题:
public sealed class MyCommandBarControl : CommandBar
{
public MyCommandBarControl()
{
this.DefaultStyleKey = typeof(MyCommandBarControl);
//this.PrimaryCommands = new ObservableCollection<ICommandBarElement>();
}
//public ObservableCollection<ICommandBarElement> PrimaryCommands
//{
// get { return (ObservableCollection<ICommandBarElement>)GetValue(PrimaryCommandsProperty); }
// set { SetValue(PrimaryCommandsProperty, value); }
//}
///// <summary>
///// PrimaryCommands Dependency Property
///// </summary>
//public static readonly DependencyProperty PrimaryCommandsProperty =
// DependencyProperty.Register(
// "PrimaryCommands",
// typeof(ObservableCollection<ICommandBarElement>),
// typeof(MainPage),
// new PropertyMetadata(null, null));
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var primaryItemsControl = GetTemplateChild("PrimaryItemsControl") as ItemsControl;
primaryItemsControl.ItemsSource = this.PrimaryCommands;
}
}
<强> [UPDATE1] 强>
我认为存在我们看不到的基础类型转换,或者我们必须使用某些接口,例如ICommandBar,但由于其保护级别,我们无法使用。
如果您希望自己实现CommandBar,我认为创建自己的Command按钮而不是使用AppBarButton会更好。 但是你需要确保你有充分的理由自己做。
例如,如果我使用默认Button,则以下内容将起作用。
public sealed class MyCommandBarControl : ContentControl
{
public MyCommandBarControl()
{
this.DefaultStyleKey = typeof(MyCommandBarControl);
this.PrimaryCommands = new ObservableCollection<Button>();
}
public ObservableCollection<Button> PrimaryCommands
{
get { return (ObservableCollection<Button>)GetValue(PrimaryCommandsProperty); }
set { SetValue(PrimaryCommandsProperty, value); }
}
/// <summary>
/// PrimaryCommands Dependency Property
/// </summary>
public static readonly DependencyProperty PrimaryCommandsProperty =
DependencyProperty.Register(
"PrimaryCommands",
typeof(ObservableCollection<Button>),
typeof(MainPage),
new PropertyMetadata(null, null));
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var primaryItemsControl = GetTemplateChild("PrimaryItemsControl") as ItemsControl;
primaryItemsControl.ItemsSource = this.PrimaryCommands;
}
}
在MainPage.xaml
中 <local:MyCommandBarControl>
<local:MyCommandBarControl.Content>
<TextBlock Text="My CommandBar" />
</local:MyCommandBarControl.Content>
<local:MyCommandBarControl.PrimaryCommands>
<Button Content="Pin" Click="PinBarButton_Click" />
<Button Content="UnPin" />
<Button Content="Sync" />
<Button Content="Remove" />
</local:MyCommandBarControl.PrimaryCommands>
</local:MyCommandBarControl>