【问题标题】:Handle UWP AutoSuggestionBox events the MVVM way以 MVVM 方式处理 UWP AutoSuggestionBox 事件
【发布时间】:2019-05-04 01:24:42
【问题描述】:

我正在尝试创建一个AutoSuggestBox,允许用户搜索特定的气象站。

为了处理 TextChanged 事件,我在标记中添加了到相应 ViewModel 属性的绑定:

    <AutoSuggestBox Grid.Row="1" 
                    PlaceholderText="Station" 
                    VerticalAlignment="Center" 
                    QueryIcon="Forward"
                    Width="300"
                    Height="50"
                    DisplayMemberPath="Name"
                    TextMemberPath="Name"
                    ItemsSource="{Binding Path=Stations}">

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

    </AutoSuggestBox>

我的 ViewModel 如下所示:

public class StationCollectionVM : INotifyPropertyChanged
{
    private IStationManager stationManager;
    private ICommand textChanged;

    public ObservableCollection<StationVM> Stations { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;

    public StationCollectionVM(IStationManager stationManager)
    {
        this.stationManager = stationManager;
        Stations = new ObservableCollection<StationVM>();
        LoadStations();
    }

    private async void LoadStations()
    {
        Stations.Clear();
        IEnumerable<Station> stations = await stationManager.GetAllStationsAsync();
        IEnumerator<Station> e = stations.GetEnumerator();
        while (await Task.Factory.StartNew(() => e.MoveNext()))
        {
            Stations.Add(new StationVM(stationManager, e.Current));
        }
    }

    public ICommand TextChanged
    {
        get
        {
            if (textChanged == null)
            {
                textChanged = new RelayCommand(args =>
                {
                    // ICommand.Execute(...) takes only 1 param.
                    // How do you get both the AutoSuggestBox and 
                    // AutoSuggestBoxTextChangedEventArgs param
                    // sent from the AutoSuggestBox?

                    // Filter stations based on the user input here...
                });
            }
            return textChanged;
        }
    }
}

请注意RelayCommand 只是ICommand 的一个实现:

public class RelayCommand : ICommand
{
    readonly Action<object> executeAction;
    readonly Predicate<object> canExecutePredicate;

    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action<object> execute)
      : this(execute, null)
    {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        executeAction = execute ?? throw new ArgumentNullException(nameof(execute));
        canExecutePredicate = canExecute;
    }

    public void Execute(object parameter)
    {
        executeAction(parameter);
    }

    public bool CanExecute(object parameter)
    {
        return canExecutePredicate == null ? true : canExecutePredicate(parameter);
    }

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, new EventArgs());
    }
}

如何访问StationCollectionVMTextChanged 属性中的两个事件参数?另外,将过滤后的电台列表传回 AutoSuggestBox 的首选方式是什么?

【问题讨论】:

    标签: c# mvvm uwp .net-core


    【解决方案1】:

    如果你只是想根据AutoSuggestBox的输入值过滤数据,那么只需要1个参数就足够了。您可以将AutoSuggestBoxText 属性作为CommandParamenter 传递,如下所示:

    <AutoSuggestBox x:Name="autoSuggestBox" 
                            Grid.Row="1" 
                            PlaceholderText="Station" 
                            VerticalAlignment="Center" 
                            QueryIcon="Forward"
                            Width="300"
                            Height="50"
                            DisplayMemberPath="Name"
                            TextMemberPath="Name"
                            ItemsSource="{Binding Path=ComboBoxList}">
    
                    <interactivity:Interaction.Behaviors>
                        <core:EventTriggerBehavior EventName="TextChanged">
                            <core:InvokeCommandAction Command="{Binding TextChanged}" CommandParameter="{Binding Text, ElementName=autoSuggestBox}"></core:InvokeCommandAction>
                        </core:EventTriggerBehavior>
                    </interactivity:Interaction.Behaviors>
    
    </AutoSuggestBox>
    

    另外,请注意,您需要额外的属性来存储您的实际集合,如果没有过滤器值,您可以检索这些属性。

    你的虚拟机:

    public class StationCollectionVM : INotifyPropertyChanged
    {
        private IStationManager stationManager;
        private ICommand textChanged;
        private IEnumerable<StationVM> stationsVM { get; set; }
    
        public ObservableCollection<StationVM> Stations { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
    
        public StationCollectionVM(IStationManager stationManager)
        {
            this.stationManager = stationManager;
            Stations = new ObservableCollection<StationVM>();
            LoadStations();
        }
    
        private async void LoadStations()
        {
            Stations.Clear();
            IEnumerable<Station> stations = await stationManager.GetAllStationsAsync();
            IEnumerator<Station> e = stations.GetEnumerator();
            while (await Task.Factory.StartNew(() => e.MoveNext()))
            {
                stationsVM.Add(new StationVM(stationManager, e.Current));
            }
            Stations = ObservableCollection<StationVM>(stationsVM);
        }
    
        public ICommand TextChanged
        {
            get
            {
                if (textChanged == null)
                {
                    textChanged = new RelayCommand(args =>
                    {
                       if(!string.IsEmpty(args))
                       {
                         Stations = staionsVM.Where(x=>x.SomeTextProperty.StartsWith(args));
                       }
                       else
                       {
                         Stations = ObservableCollection<StationVM>(stationsVM);
                       }
                    });
                }
                return textChanged;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-05
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-27
      • 1970-01-01
      相关资源
      最近更新 更多