c# - UWP:为什么 DataTemplate 中的行为有一个空的 AssociatedObject?
问题描述
我想将 NavigationView Header 上的 CommandBar 绑定到一个集合以动态显示 AppBarButtons,我使用了这个答案中给出的方法。但是,当我在 DataTemplate 中的 CommandBar 上设置行为并运行程序时,它会引发异常,显示 AssociatedObject 为空。这是代码:
xaml:
<i:Interaction.Behaviors>
<behaviors:NavigationViewHeaderBehavior
DefaultHeader="{x:Bind ViewModel.Selected.Content, Mode=OneWay}">
<behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate>
<DataTemplate>
<Grid>
<CommandBar Name="headerCommandBar">
<i:Interaction.Behaviors>
<behaviors:BindableCommandBarBehavior
PrimaryCommands="{Binding Path=Content.ViewModel.AppBarButtonList,ElementName=shellFrame, Mode=OneWay}" />
</i:Interaction.Behaviors>
</CommandBar>
</Grid>
</DataTemplate>
</behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate>
</behaviors:NavigationViewHeaderBehavior>
</i:Interaction.Behaviors>
ViewModel 中的 C# 代码:
public ObservableCollection<AppBarButton> AppBarButtonList { get; set; }
= new ObservableCollection<AppBarButton>
{
new AppBarButton { Icon = new SymbolIcon(Symbol.Accept), Label="Accept" },
new AppBarButton { Icon = new SymbolIcon(Symbol.Add), Label="Add" }
};
行为准则:
public class BindableCommandBarBehavior : Behavior<CommandBar>
{
public ObservableCollection<AppBarButton> PrimaryCommands
{
get { return (ObservableCollection<AppBarButton>)GetValue(PrimaryCommandsProperty); }
set { SetValue(PrimaryCommandsProperty, value); }
}
public static readonly DependencyProperty PrimaryCommandsProperty
= DependencyProperty.Register(
"PrimaryCommands",
typeof(ObservableCollection<AppBarButton>),
typeof(BindableCommandBarBehavior),
new PropertyMetadata(default(ObservableCollection<AppBarButton>), UpdateCommands));
private static void UpdateCommands(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (!(dependencyObject is BindableCommandBarBehavior behavior)) return;
var oldList = dependencyPropertyChangedEventArgs.OldValue as ObservableCollection<AppBarButton>;
if (dependencyPropertyChangedEventArgs.OldValue != null)
{
oldList.CollectionChanged -= behavior.PrimaryCommandsCollectionChanged;
}
var newList = dependencyPropertyChangedEventArgs.NewValue as ObservableCollection<AppBarButton>;
if (dependencyPropertyChangedEventArgs.NewValue != null)
{
newList.CollectionChanged += behavior.PrimaryCommandsCollectionChanged;
}
behavior.UpdatePrimaryCommands();
}
private void PrimaryCommandsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
UpdatePrimaryCommands();
}
/// <summary>
/// Update the primary commands for CommandBar.
/// </summary>
private void UpdatePrimaryCommands()
{
if (PrimaryCommands != null)
{
AssociatedObject.PrimaryCommands.Clear();
foreach (var command in PrimaryCommands)
{
AssociatedObject.PrimaryCommands.Add(command);
}
}
}
protected override void OnDetaching()
{
base.OnDetaching();
if (PrimaryCommands != null)
{
PrimaryCommands.CollectionChanged -= PrimaryCommandsCollectionChanged;
}
}
}
在 UpdatePrimaryCommands 方法中引发异常。我想知道为什么会这样。
解决方案
您的命令在AssociatedObject
实际附加之前已更新。添加测试AssociatedObject != null
inUpdateCommands
并创建OnAttached
将UpdateCommands
再次调用的方法:
/// <summary>
/// Update the primary commands for CommandBar.
/// </summary>
private void UpdatePrimaryCommands()
{
if (PrimaryCommands != null && AssociatedObject != null)
{
AssociatedObject.PrimaryCommands.Clear();
foreach (var command in PrimaryCommands)
{
AssociatedObject.PrimaryCommands.Add(command);
}
}
}
protected override void OnAttached()
{
UpdatePrimaryCommands();
}
推荐阅读
- bash - Mac Shell .sh 命令不可能
- drools - Drools 中 @duration 和 @expires 的区别
- python - 如何在 Linux Azure Web App 上安装和配置 Oracle Instant Client
- r - 排除分组以在 tidyverse 中运行统计测试
- animation - 贝塞尔曲线的速度运动图
- php - 理解 php 的河豚检查
- spring - Grafana 使用 http_server_requests_seconds_count 绘制每分钟的 HTTP 请求数
- python - 将压缩的 Python 文件更改为可执行文件
- datadog - 如何在 DataDog 中的时间序列上设置线条颜色
- string - 从字符串中提取字符串标记对象?