Silverlight中使用MVVM(6):AutoComplteBox的异步过滤
Silverlight中使用MVVM(5)-Command II
Toolkit中AutoCompleteBox控件的功能非常强大,其用法可以参考AutoCompleteBox的基本使用这篇文章。
在实际的开发中,数据一般通过WCF异步传递的,要实现AutoCompleteBox的过滤数据,主要用到的是Populating事件和PopulateComplete方法
private void autoCompleteBox1_Populating(object sender, PopulatingEventArgs e)
{
ServiceAPI.FilterServiceClient filterServiceClient = new FilterServiceClient();
filterServiceClient.DoWorkCompleted += (obj, arg) =>
{
this.autoCompleteBox1.ItemsSource = arg.Result;
this.autoCompleteBox1.PopulateComplete();
};
filterServiceClient.DoWorkAsync();
}
上面的代码是比较常见的操作方式,这里我们关注一下如何使用MVVM的方式将其分离到ViewModel中
首先定义名为FilterAsyncParameters的类,其有2个属性,FilterCriteria表示过滤参数,即文本框中的值,FilterComplete 则封装了下PopulateComplete方法
public class FilterAsyncBehavior : Behavior<AutoCompleteBox>
{
public ICommand FilterAsyncCommand
{
get
{
return (ICommand)GetValue(FilterAsyncCommandProperty);
}
set
{
SetValue(FilterAsyncCommandProperty, value);
}
}
public static readonly DependencyProperty FilterAsyncCommandProperty = DependencyProperty.Register("FilterAsyncCommand",
typeof(ICommand),
typeof(FilterAsyncBehavior),
new PropertyMetadata(null));
...
}
这里定义的FilterAsyncCommand用于执行ViewModel里面的ICommand,FilterAsyncBehavior重写了OnAttached,OnDetaching方法
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Populating += AssociatedObject_Populating;
}
protected override void OnDetaching()
{
AssociatedObject.Populating -= AssociatedObject_Populating;
base.OnDetaching();
}
private void AssociatedObject_Populating(object sender, PopulatingEventArgs e)
{
ICommand filterCommand = FilterAsyncCommand;
if (filterCommand != null)
{
//创建过滤参数
var parameters = new FilterAsyncParameters(AssociatedObject.PopulateComplete, e.Parameter);
filterCommand.Execute(parameters);
e.Cancel = true;
}
}
ViewModel中定义了ICommand属性
public AcbAsyncViewModel()
{FilterCommand = new RelayCommand<FilterAsyncParameters>(ExecuteFilter);
}
private void ExecuteFilter(FilterAsyncParameters filterAsyncParameters)
{
ServiceAPI.FilterServiceClient filterServiceClient=new FilterServiceClient();
filterServiceClient.DoWorkCompleted += (obj, arg) =>
{
…..var filter = arg.UserState as FilterAsyncParameters;
filter.FilterComplete();
};
filterServiceClient.DoWorkAsync(filterAsyncParameters);
}
View中Xaml代码
<sdk:AutoCompleteBox ItemsSource="{Binding Data}">
<interactivity:Interaction.Behaviors>
<utilities:FilterAsyncBehavior FilterAsyncCommand="{Binding FilterCommand}" />
</interactivity:Interaction.Behaviors>
</sdk:AutoCompleteBox>