无法绑定Autocompletebox的Behavior属性

时间:2014-07-14 05:41:02

标签: c# wpf silverlight xaml mvvm

这是一个silverlight应用程序,我对自动完成框使用异步过滤,问题是到目前为止我无法将FilterAsyncCommand属性与相应的ViewModel属性的行为绑定。

以下是视图中控件的xaml声明:

<controls:ChildWindow x:Class="MyApp.Views.View1"
              xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  
              xmlns:fw ="clr-namespace:NetBoxSys.Views"
              ...    
>

     <sdk:AutoCompleteBox 
        MinimumPrefixLength="3" MinimumPopulateDelay="150" 
        SelectedItem="{Binding Path=...}" ItemsSource="{Binding Path=...}"  >
        <i:Interaction.Behaviors>
           <fw:FilterAsyncBehavior FilterAsyncCommand="{Binding Path=FilterAsyncCommand}" />
        </i:Interaction.Behaviors>
     </sdk:AutoCompleteBox>

</controls:ChildWindow>

... ViewModel代码:

private ICommand filterAsyncCommand;
        public ICommand FilterAsyncCommand {
            get { return filterAsyncCommand; }
            set {
                filterAsyncCommand = value;
                this.OnPropertyChanged( "FilterAsyncCommand" );
            }
        }

...这就是我加载视图的方式

var  view = new View1();
view.DataContext = new ViewModel1();
view.Show(); //Modal

我也尝试过这种语法,但也不起作用:

<fw:FilterAsyncBehavior FilterAsyncCommand="{Binding FilterAsyncCommand}" />

需要有关此类绑定的建议。

更新: 行为代码:

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));        

        protected override void OnAttached()
        {
            base.OnAttached();

            // handle the populating event of the associated auto complete box
            AssociatedObject.Populating += AssociatedObject_Populating;
        }

        protected override void OnDetaching()
        {
            // detach the event handler
            AssociatedObject.Populating -= AssociatedObject_Populating;

            base.OnDetaching();
        }

        private void AssociatedObject_Populating(object sender, PopulatingEventArgs e)
        {
            // get the command
            ICommand filterCommand = FilterAsyncCommand;

            if (filterCommand != null)
            {
                // create the parameters for the command
                var parameters = new FilterAsyncParameters(AssociatedObject.PopulateComplete, e.Parameter);

                // execute command
                filterCommand.Execute(parameters);

                // cancel the population of the auto complete box
                e.Cancel = true;
            }
        }
    }

ViewModel代码:

public class ViewModel1 : ViewModel, IViewModel {


        public ViewModel1() {
            //Initializing the command in constructor
            FilterAsyncCommand = new DelegateCommand<FilterAsyncParameters>( ExecuteFilterAsync );            
        }

        private void ExecuteFilterAsync( FilterAsyncParameters args ) {
            ....
        }

        private ICommand filterAsyncCommand;
        public ICommand FilterAsyncCommand {
            get { return filterAsyncCommand; }
            set {
                filterAsyncCommand = value;
                this.OnPropertyChanged( "FilterAsyncCommand" );
            }
        }
}

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法。我放弃在运行时传递ViewModel,所以我改为MVVM模式的以下实现

 <controls:ChildWindow x:Class="MyApp.Views.View1"
                  xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  
                  xmlns:fw ="clr-namespace:NetBoxSys.Views"
                  ...    
    >

    <controls:ChildWindow.Resources>
        <viewModel:ViewModelRecepcionOCViewModelLocator x:Key="viewModelLocator"/>
    </controls:ChildWindow.Resources>

    <controls:ChildWindow.DataContext>
      <Binding Source="{StaticResource viewModelLocator}" Path="ViewModel" />
    </controls:ChildWindow.DataContext>

<sdk:AutoCompleteBox HorizontalAlignment="Stretch" Margin="2" x:Name="remitente_Autocomplete" VerticalAlignment="Center" Grid.Column="1" Grid.Row="4"
                                    MinimumPrefixLength="3" MinimumPopulateDelay="150" Padding="0" Height="23" TabIndex="1" Text="{Binding Path=NombreRemitente,Mode=TwoWay}"
                                SelectedItem="{Binding Path=SelectedRemitente,Mode=TwoWay}" ItemsSource="{Binding Path=Remitentes}"  >
                <i:Interaction.Behaviors>
                  <fw:FilterAsyncBehavior FilterAsyncCommand="{Binding Source={StaticResource viewModelLocator},Path=ViewModel.FilterAsyncCommand}" />
                </i:Interaction.Behaviors>
            </sdk:AutoCompleteBox>

</controls:ChildWindow>

这里重要的部分是FilterAsyncCommand的绑定定义。 并且RecepcionOCViewModelLocator定义如下

public class RecepcionOCViewModelLocator : ViewModelLocatorBase<IRecepcionOCViewModel>
{
   public IRecepcionOCViewModel ViewModel{get;set;}
}