在MVVM中UWP绑定到AutoSuggestBox
我正在调用UWP中AutoSuggestBox控件的QuerySubmitted命令。 该命令绑定到视图模型中的ICommand。 问题是它需要接受AutoSuggestBoxQuerySubmittedEventArgs,这是纯UI,在MVVM中是不可接受的 我的代码如下所示:在MVVM中UWP绑定到AutoSuggestBox,mvvm,binding,uwp,autosuggest,Mvvm,Binding,Uwp,Autosuggest,我正在调用UWP中AutoSuggestBox控件的QuerySubmitted命令。 该命令绑定到视图模型中的ICommand。 问题是它需要接受AutoSuggestBoxQuerySubmittedEventArgs,这是纯UI,在MVVM中是不可接受的 我的代码如下所示: <AutoSuggestBox Name="SearchAutoSuggestBox" PlaceholderText="Search by keywords"
<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
}
我的视图模型如下所示:
<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
}
public DelegateCommand SearchCommand{get;}
公共MainPageViewModel()
{
SearchCommand=新的DelegateCommand(ExecuteMethod);
}
私有void执行方法(AutoSuggestBoxQuerySubmittedEventArgs o)
{
//代码在这里
}
ofcours AutoSuggestBoxQuerySubmittedEventArgs在视图模型中不可接受。
寻找替代品。。。
如果您不介意使用非纯MVVM方式,SuggestionSelected…
MainPage.xaml
:
<AutoSuggestBox Name="SearchAutoSuggestBox"
PlaceholderText="Search by keywords"
QueryIcon="Find" QuerySubmitted="{x:Bind ViewModel.SearchQuerySubmitted}" IsEnabled="{x:Bind ViewModel.CanExecuteSearchCommand, Mode=TwoWay}"
>
</AutoSuggestBox>
MainPage.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));
}
}
MainPageViewModel ViewModel = new MainPageViewModel();
可以将搜索字符串(文本属性)绑定到视图模型属性,将事件绑定到无参数方法。这样,视图模型就不必处理UI对象: XAML:
代码隐藏:
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 */ }
}
public类MainPageViewModel:SomeViewModelBaseClass
{
/*不包括样板代码和构造函数*/
私有字符串_SearchText;
公共字符串SearchText{/*getter和setter INotyfyPropertyChange兼容*/}
私有列表_Usuals;//在构造函数上初始化
公共字符串通常{/*getter和setter INotyfyPropertyChange兼容*/}
公共空过滤器常用()
{
//搜索字符串位于SearchText示例中:
Usuals=\u usualstore.Where(u=>u.Contains(\u SearchText.ToLower()).ToList();
}
public void ProcessQuery(){/*TODO-搜索字符串位于SearchText*/}
public void ProcessChoice(){/*TODO-搜索字符串位于SearchText*/}
}
InvokeCommandAction有一个名为InputConverter的参数,您可以使用该参数将事件参数转换为可以传递给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>
最后,在viewmodel中更改命令以接受字符串作为参数。因此,您的虚拟机中将包含以下内容:
public DelegateCommand<string> SearchCommand { get; }
public MainPageViewModel()
{
SearchCommand = new DelegateCommand<string>(ExecuteMethod);
}
private void ExecuteMethod(string o)
{
// CODE HERE
}
public DelegateCommand SearchCommand{get;}
公共MainPageViewModel()
{
SearchCommand=新的DelegateCommand(ExecuteMethod);
}
私有void ExecuteMethod(字符串o)
{
//代码在这里
}
UWP绑定Command/Delegate
到MVVM中的AutoSuggestBox
用于超宽带移动应用
创建一个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());
}
}
}
EventTriggerBehavior的MSDN页面表示只支持事件的一个子集,QuerySubmitted不是其中之一。您是否实施了新的行为以使其正常工作?
<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>
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; }
}