模板 10 UWP 如何绑定到 MenuFlyoutItem 内的 autoSuggestBox

Template 10 UWP How to bind to a autoSuggestBox inside a MenuFlyoutItem

我正在使用 MVVM 模式将 ViewPage 中的 AutoSuggestBox 的属性绑定到我的 ViewModel。当我在 Grid 或 stackPanel 中时,这很好用。

但是一旦我将 AutoSuggestBox 放入按钮的 MenuFlyout 中。我在编译时收到以下错误

错误对象引用未设置到对象的实例。

关于如何在 MenuFlyoutItem 中绑定 AutoSuggestBox 的属性的任何指导??

这是我要编译的代码。

<Button>
  <Button.Flyout>
    <MenuFlyoutItem >
          <MenuFlyoutItem.Template>
             <ControlTemplate TargetType="MenuFlyoutItem">
                 <AutoSuggestBox Header="What's your name?"
                  TextChanged="{x:Bind ViewModel.FilterUsuals}"
                  QuerySubmitted="{x:Bind ViewModel.ProcessQuery}"
                  SuggestionChosen="{x:Bind ViewModel.ProcessChoice}"
                  ItemsSource="{Binding Elements}"
                  Text="{x:Bind ViewModel.SearchText, Mode=TwoWay}"
                  QueryIcon="Find" />
            </ControlTemplate>
          </MenuFlyoutItem.Template>
    </MenuFlyoutItem>
</Button.Flyout>
</Button >
  <Button Content="Button"  Margin="10,0"  >
    <Button.Flyout>
        <Flyout  Placement="Top">
               <AutoSuggestBox ... />
         </Flyout>
    </Button.Flyout>
  </Button>

不确定是否需要将它放在 MenuFlyout 中。当它可以只在按钮本身的 Flyout 子类型中时,为什么要这样做让自己如此痛苦?

绑定与Template10无关。它可能与未初始化的集合有关。验证您绑定的那些集合是否已正确创建(例如 new List<yourtype>()

我认为您的错误是因为您使用的 ControlTemplate 会立即更改页面的数据上下文,从而使您的 ViewModel 超出范围。更重要的是 x:Bind 在 ControlTemplates 中不受支持。这意味着您不能使用方便的 x:Bind 事件,并且需要创建命令。您将不得不使用行为来最轻松地完成此操作。

与此类似。

<AutoSuggestBox>
   <interactivity:Interaction.Behaviors>
      <core:EventTriggerBehavior EventName="TextChanged">
         <core:InvokeCommandAction Command="{Binding TextChangedCommand}" />
      </core:EventTriggerBehavior>
   </interactivity:Interaction.Behaviors>
</AutoSuggestBox>

或类似于此。

public class AutoSuggestBoxAttachedProperties : Windows.UI.Xaml.DependencyObject
{
    public static ICommand GetTextChangedCommand(Windows.UI.Xaml.Controls.AutoSuggestBox obj)
        => (ICommand)obj.GetValue(TextChangedCommandProperty);
    public static void SetTextChangedCommand(Windows.UI.Xaml.Controls.AutoSuggestBox obj, ICommand value)
        => obj.SetValue(TextChangedCommandProperty, value);
    public static readonly DependencyProperty TextChangedCommandProperty =
        DependencyProperty.RegisterAttached("TextChangedCommand", typeof(ICommand),
            typeof(AutoSuggestBoxAttachedProperties), new PropertyMetadata(null, TextChangedCommandChanged));

    public static object GetTextChangedCommandParameter(Windows.UI.Xaml.Controls.AutoSuggestBox obj)
        => (object)obj.GetValue(TextChangedCommandParameterProperty);
    public static void SetTextChangedCommandParameter(Windows.UI.Xaml.Controls.AutoSuggestBox obj, object value)
        => obj.SetValue(TextChangedCommandParameterProperty, value);
    public static readonly DependencyProperty TextChangedCommandParameterProperty =
        DependencyProperty.RegisterAttached("TextChangedCommandParameter", typeof(object),
            typeof(AutoSuggestBoxAttachedProperties), new PropertyMetadata(null));

    private static void TextChangedCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var box = d as Windows.UI.Xaml.Controls.AutoSuggestBox;
        box.TextChanged -= Box_TextChanged;
        if (e.NewValue != null)
        {
            box.TextChanged += Box_TextChanged;
        }
    }

    private static void Box_TextChanged(Windows.UI.Xaml.Controls.AutoSuggestBox sender, Windows.UI.Xaml.Controls.AutoSuggestBoxTextChangedEventArgs args)
    {
        var command = GetTextChangedCommand(sender);
        if (command != null)
        {
            var parameter = GetTextChangedCommandParameter(sender);
            command.Execute(parameter);
        }
    }
}

然后这个。

<AutoSuggestBox 
    ex:AutoSuggestBoxAttachedProperties.TextChangedCommand="{Binding TextChangedCommand}" />

祝你好运。 /杰瑞