2013-04-18 126 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,爲什麼不使用專爲此目的而設計的繼電器命令? –