我想将NavigationView Header上的CommandBar绑定到一个集合以动态显示AppBarButtons,我使用了此答案中给出的方法。但是,当我在DataTemplate中的CommandBar上设置行为并运行该程序时,它将引发异常,表明AssociatedObject为null。这是代码:
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
in的测试UpdateCommands
并创建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();
}
解决了问题,谢谢您的回复^ _ ^