2013-04-18 92 views
0

我开发基于WPF + MVVM的Prism + MEF应用程序,其中有许多DataGrid,因此我构建DataGridStyle以应用于所有模块中的所有DataGrid。风格添加在列头过滤器文本框中,我用MVVM光EventToCommand触发TextChanged事件时,文本框中的文本改变这样的:(此代码DataGridStyle资源字典中存在)WPF-MVVM:从DataGrid风格的Handeling事件

<TextBox x:Name="filterTextBox" 
     HorizontalAlignment="Right" MinWidth="25" Height="Auto" 
     OpacityMask="Black" Visibility="Collapsed" 
     Text="" 
     TextWrapping="Wrap" Grid.Column="0" Grid.ColumnSpan="1"> 

      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="TextChanged"> 
        <cmd:EventToCommand Command="{Binding DataContext.TextChangedCommand}" 
          PassEventArgsToCommand="True"/> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
    </TextBox> 

然后我处理在视图模型的TextChangedCommand(与查看包含数据网格)使用附加属性:

#region TextChangedCommand---------------------------------------------------------------------------------------------- 

     static ICommand command; //1 

     public static ICommand GetTextChangedCommand(DependencyObject obj) 
     { 
      return (ICommand)obj.GetValue(TextChangedCommandProperty); 
     } 

     public static void SetTextChangedCommand(DependencyObject obj, ICommand value) 
     { 
      obj.SetValue(TextChangedCommandProperty, value); 
     } 

     // Using a DependencyProperty as the backing store for TextChangedCommand. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty TextChangedCommandProperty = 
      DependencyProperty.RegisterAttached("TextChangedCommand", 
               typeof(ICommand), 
               typeof(SubsystemAllViewModel), 
               new UIPropertyMetadata(null, CommandChanged)); 


     static void CommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
     { 
      var fe = obj as FrameworkElement; 
      command = e.NewValue as ICommand; 
      fe.AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(ExecuteCommand)); 
     } 

     static void ExecuteCommand(object sender, TextChangedEventArgs e) 
     { 
      //Some Code 
     } 


     #endregion 

和包含网格视图:

<DataGrid ItemsSource="{Binding Subsystems,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
        SelectedItem="{Binding Path=SelectedSubsystem, Mode=TwoWay}"       
        Name="SubsystemAllDataGrid"    
        Style="{StaticResource DataGridStyle}" 
        Grid.Row="2"> 

      <DataGrid.Columns> 
       <DataGridTextColumn Header="Serial" Binding="{Binding Path=Serial, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Type" Binding="{Binding Path=Type, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="System" Binding="{Binding Path=System, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="SubsystemNo" Binding="{Binding Path=SubsystemNo, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Description" Binding="{Binding Path=Description, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Scope" Binding="{Binding Path=Scope, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Area" Binding="{Binding Path=Area, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Priority" Binding="{Binding Path=Priority, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="DossierLocation" Binding="{Binding Path=DossierLocation, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Parts" Binding="{Binding Path=Parts, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Status" Binding="{Binding Path=Status, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="StatusDate" Binding="{Binding Path=StatusDate, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="MCDate" Binding="{Binding Path=MCDate, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="PlnMCDate" Binding="{Binding Path=PlnMCDate, Mode=TwoWay}"></DataGridTextColumn> 
       <DataGridTextColumn Header="Remark" Binding="{Binding Path=Remark, Mode=TwoWay}"></DataGridTextColumn> 

      </DataGrid.Columns> 

     </DataGrid> 

的问题是: 当我在文本框中在数据网格中没有的列标题的一个输入过滤文本发生在以下几点打不破发点:

1 GetTextChangedCommand和SetTextChangedCommand

2 CommandChanged()方法。

我是wpf的新手,所以我确定在WPF或C#代码中存在错误...所以请帮我解决这些错误。

注意:我不使用代码。

在此先感谢

+0

这似乎是一个MVVM光的特定问题。 –

回答

0

看起来像你的命令绑定不起作用。请尝试以下操作:

Command="{Binding Path=TextChangedCommand}" 

Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}} Path=DataContext.TextChangedCommand}" 
+0

我应用了这两个选项,但是当我在任何列标题的过滤器文本框中输入过滤器文本时,仍然没有发生任何事情。 – Hussein

+0

为什么不把TextBox的Text属性绑定到ViewModel中的一个属性。所以你可以在这个属性的setter中调用TextChangedCommand。 –

+0

我试过这样做,但我有两个问题,第一个:调用getter,但setter从未调用,我不知道为什么。第二个问题:我需要使用EventToCommand将事件参数传递给View Model – Hussein

0

断点未命中让我的东西的结合问题。

您的datacontext命令需要设置为您的命令定义的位置。所以如果你的命令是在视图模型中定义的,你需要使用下面的代码,但是将ansestor类型设置为绑定到你的视图模型的对象类型。这通常是你的看法,而不是数据网格:

Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ViewType}} Path=DataContext.TextChangedCommand}" 

所以,如果您的视图是一个窗口或用户控制,则ViewType更改为相应的类型。

当您运行应用程序时,您还可以查看是否在输出窗口中为您的命令生成了任何绑定错误。

编辑1: 不要在您的视图模型中使用依赖属性,使用继电器命令从MVVM光强:

this.YourRelayCommand = new RelayCommand(ExecuteYourCommand, CanYourCommandExecute); 

    public RelayCommand YourRelayCommand{ get; private set; } 

    public bool CanYourCommandExecute() { 

    } 

    public void ExecuteYourCommand() { 
    //TODO: Do code here 
    } 
+0

@J King:当我在过滤器文本框中输入文本时,仍然没有发生任何事情。顺便说一句,我插入一个断点在附加属性RegisterAttached语句中打开视图时打开。 – Hussein

+0

你可以发布你的视图和数据网格被定义的整个xaml吗?你的输出窗口中是否有绑定错误? –

+1

另外,如果您使用MVVM-Light,为什么不使用专为此目的而设计的继电器命令? –