UWP 绑定到 MVVM 中的 AutoSuggestBox
Posted
技术标签:
【中文标题】UWP 绑定到 MVVM 中的 AutoSuggestBox【英文标题】:UWP Binding to AutoSuggestBox in MVVM 【发布时间】:2016-04-09 18:59:47 【问题描述】:我正在 UWP 中调用 AutoSuggestBox 控件的 QuerySubmitted 命令。 该命令绑定到视图模型中的 ICommand。 问题是它需要接受纯 UI 的 AutoSuggestBoxQuerySubmittedEventArgs,它在 MVVM 中是不可接受的。
我的代码是这样的:
<AutoSuggestBox Name="SearchAutoSuggestBox"
PlaceholderText="Search by keywords"
QueryIcon="Find"
>
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="QuerySubmitted">
<core:InvokeCommandAction Command="x:Bind ViewModel.SearchCommand" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AutoSuggestBox>
我的视图模型看起来像这样:
public DelegateCommand<AutoSuggestBoxQuerySubmittedEventArgs> SearchCommand get;
public MainPageViewModel()
SearchCommand = new DelegateCommand<AutoSuggestBoxQuerySubmittedEventArgs>(ExecuteMethod);
private void ExecuteMethod(AutoSuggestBoxQuerySubmittedEventArgs o)
// CODE HERE
ofcours AutoSuggestBoxQuerySubmittedEventArgs 在视图模型中是不可接受的。 寻找替代品... 同样适用于 SuggestionChosen...
【问题讨论】:
EventTriggerBehavior 的 MSDN 页面表示仅支持事件的子集,而 QuerySubmitted 不是其中之一。您是否为此实施了新行为? 【参考方案1】:InvokeCommandAction 有一个名为 InputConverter 的参数,您可以使用该参数将事件 args 转换为可以传递给 ViewModel 的其他参数。
首先创建一个 IValueConverter 类以从事件参数中提取您需要的内容,如下所示:-
public class AutoSuggestQueryParameterConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter, string language)
// cast value to whatever EventArgs class you are expecting here
var args = (AutoSuggestBoxQuerySubmittedEventArgs)value;
// return what you need from the args
return (string)args.ChosenSuggestion;
然后像这样在您的 XAML 中使用该转换器:
<Page.Resources>
<converters:AutoSuggestQueryParameterConverter x:Key="ArgsConverter" />
</Page.Resources>
<AutoSuggestBox Name="SearchAutoSuggestBox"
PlaceholderText="Search by keywords"
QueryIcon="Find">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="QuerySubmitted">
<core:InvokeCommandAction
Command="x:Bind ViewModel.SearchCommand"
InputConverter="StaticResource ArgsConverter" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</AutoSuggestBox>
最后在您的视图模型中更改您的命令以接受字符串作为参数。所以你的虚拟机里会有以下内容:
public DelegateCommand<string> SearchCommand get;
public MainPageViewModel()
SearchCommand = new DelegateCommand<string>(ExecuteMethod);
private void ExecuteMethod(string o)
// CODE HERE
【讨论】:
【参考方案2】:您可以将搜索字符串(文本属性)绑定到视图模型属性,并将事件绑定到无参数方法。这样视图模型就不必处理 UI 对象了:
XAML:
<AutoSuggestBox Header="What's your name?"
TextChanged="x:Bind ViewModel.FilterUsuals"
QuerySubmitted="x:Bind ViewModel.ProcessQuery"
SuggestionChosen="x:Bind ViewModel.ProcessChoice"
ItemsSource="x:Bind ViewModel.Usuals, Mode=OneWay"
Text="x:Bind ViewModel.SearchText, Mode=TwoWay"
QueryIcon="Find" />
后面的代码:
public class MainPageViewModel : SomeViewModelBaseClass
/* Boilerplate code and constructor not included */
private string _SearchText;
public string SearchText /* getter and setter INotyfyPropertyChange compliant */
private List<string> _Usuals; // Initialized on constructor
public string Usuals /* getter and setter INotyfyPropertyChange compliant */
public void FilterUsuals()
// the search string is in SearchText Example:
Usuals = _UsualsStore.Where(u => u.Contains(_SearchText.ToLower())).ToList();
public void ProcessQuery() /* TODO - search string is in SearchText */
public void ProcessChoice() /* TODO - search string is in SearchText */
【讨论】:
【参考方案3】:如果你不介意使用non pure
MVVM 方式。
MainPage.xaml
:
<AutoSuggestBox Name="SearchAutoSuggestBox"
PlaceholderText="Search by keywords"
QueryIcon="Find" QuerySubmitted="x:Bind ViewModel.SearchQuerySubmitted" IsEnabled="x:Bind ViewModel.CanExecuteSearchCommand, Mode=TwoWay"
>
</AutoSuggestBox>
MainPageViewModel.cs
:
public class MainPageViewModel : INotifyPropertyChanged
private bool _canExecuteSearchCommand;
public MainPageViewModel()
this.CanExecuteSearchCommand = true;
public bool CanExecuteSearchCommand
get return _canExecuteSearchCommand;
set
bool changed = _canExecuteSearchCommand != value;
_canExecuteSearchCommand = value;
if(changed)
this.OnPropertyChanged();
public void SearchQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
// Just example disabling SearchBox
this.CanExecuteSearchCommand = false;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
MainPage.cs
:
MainPageViewModel ViewModel = new MainPageViewModel();
【讨论】:
【参考方案4】:UWP 绑定 Command/Delegate
到 AutoSuggestBox
in MVVM
对于 UWP 移动应用程序
创建一个 DelegateCommand 类
public class DelegateCommand<T> : ICommand
private readonly Action<T> executeAction;
Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged;
public DelegateCommand(Action<T> executeAction)
: this(executeAction, null)
//var a = ((Page)(((Func<object, bool>)(executeAction.Target)).Target)).Name;
//((ViewModel.VMBranchSelection)(executeAction.Target)).;
public DelegateCommand(Action<T> executeAction, Func<object, bool> canExecute)
this.executeAction = executeAction;
this.canExecute = canExecute;
public bool CanExecute(object parameter)
return canExecute == null ? true : canExecute(parameter);
public void Execute(object parameter)
executeAction((T)parameter);
public void RaiseCanExecuteChanged()
EventHandler handler = this.CanExecuteChanged;
if (handler != null)
handler(this, new EventArgs());
在视图模型中
public ICommand SuggessionSelectCity_QuerySubmitted
get return new DelegateCommand<AutoSuggestBoxQuerySubmittedEventArgs>(this.SuggessionSelectCityQuerySubmitted);
private void SuggessionSelectCityQuerySubmitted(AutoSuggestBoxQuerySubmittedEventArgs obj)
if (obj.ChosenSuggestion != null)
AutosuggestionTextBoxName.Text = ((ModelName) (obj.ChosenSuggestion)).Model's Property name;
//or
AutosuggestionTextBoxName.Text =(obj.ChosenSuggestion).property name
else
在 XAML 代码中
<AutoSuggestBox Grid.Column="1" x:Name="SuggessionSelectCity"
PlaceholderText="Search by keywords" QueryIcon="Find"
ItemsSource="Binding PApplicantCityList"
HorizontalAlignment="Center" VerticalAlignment="Center" DisplayMemberPath="Description" Width="250" Height="45">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="TextChanged">
<Core:EventTriggerBehavior.Actions>
<Core:InvokeCommandAction Command="Binding SuggessionSelectCityTextChange"/>
</Core:EventTriggerBehavior.Actions>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="QuerySubmitted">
<Core:EventTriggerBehavior.Actions>
<Core:InvokeCommandAction Command="Binding SuggessionSelectCity_QuerySubmitted"/>
</Core:EventTriggerBehavior.Actions>
</Core:EventTriggerBehavior>
<Core:EventTriggerBehavior EventName="SuggestionChosen">
<Core:EventTriggerBehavior.Actions>
<Core:InvokeCommandAction Command="Binding SuggessionSelectCitySuggestionChosen"/>
</Core:EventTriggerBehavior.Actions>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</AutoSuggestBox>
</Grid>
在视图模型中为 Autosuggestion TextBox Itemssource 创建一个列表
private ObservableCollection<ResultMasterModel> ApplicantCityList;
public ObservableCollection<ResultMasterModel> PApplicantCityList
get return ApplicantCityList;
set this.SetProperty(ref this.ApplicantCityList, value);
在上面的列表中添加一些硬编码值
在模型文件夹中创建模型
public class ResultMasterModel
public string Code get; set;
public string Description get; set;
【讨论】:
以上是关于UWP 绑定到 MVVM 中的 AutoSuggestBox的主要内容,如果未能解决你的问题,请参考以下文章