2010-03-18 48 views
2

我有一個視圖上的數據網格綁定到視圖模型。當我初始化視圖時,數據網格就會填充來自視圖模型(ObservableCollection)的數據。但是,當我嘗試對數據進行搜索時,數據網格不會從視圖模型中刷新。當我斷開viewmodel中的代碼時,我可以看到ObservableCollection中的結果在我的搜索中發生了變化,但不知何故,這些結果並沒有傳遞迴視圖。這是我的觀點和視圖模型(順便說一句,我使用VS2010 RTM):刷新viewgodel視圖上的數據網格

namespace Attendance.ViewModels 
{ 
    public class EmployeeSelectViewModel : ViewModel, INotifyPropertyChanged 
    { 
     #region Entity list and constructor 
    public EmployeeSelectViewModel() 
    { 
     { 
      Initialize(); 
     } 
    } 

    private void Initialize() 
    { 
     if (employeeRpository == null) 
      employeeRpository = new EmployeeRepository(); 

     ListOfEmployees = new ObservableCollection<EmployeeDto>(employeeRpository.GetEmployees(true)); 
    } 

    private EmployeeRepository employeeRpository; 

    private ObservableCollection<EmployeeDto> listOfEmployees; 
    public ObservableCollection<EmployeeDto> ListOfEmployees 
    { 
     get { return listOfEmployees; } 
     set 
     { 
      if (listOfEmployees != value) 
      { 
       listOfEmployees = value; 
       NotifyPropertyChanged("ListOfEmployee"); 
      } 
     } 
    } 

    private EmployeeDto selectedEmployee; 
    public EmployeeDto SelectedEmployee 
    { 
     get { return selectedEmployee; } 
     set 
     { 
      if (selectedEmployee != value) 
      { 
       selectedEmployee = value; 
       NotifyPropertyChanged("SelectedEmployee"); 
      } 
     } 
    } 

    #endregion 

    #region UI control references 

    /// <summary> 
    /// search text property 
    /// </summary> 
    private string searchText; 
    public string SearchText 
    { 
     get { return searchText; } 
     set 
     { 
      if (searchText != value) 
      { 
       searchText = value; 
       NotifyPropertyChanged("SearchText"); 
      } 
     } 
    } 

    public string Location { get; set; } 

    #endregion 

    #region Relay Commands 

    /// <summary> 
    /// new command 
    /// </summary> 
    private ViewCommand newCommand; 
    public ViewCommand NewCommand 
    { 
     get 
     { 
      if (newCommand == null) 
       newCommand = new ViewCommand(param => this.NewEmployee()); 
      return newCommand; 
     } 
    } 
    private void NewEmployee() 
    { 
     NavigationActions.NewEmployeeView(); 
    } 

    /// <summary> 
    /// edit command 
    /// </summary> 
    private ViewCommand editCommand; 
    public ViewCommand EditCommand 
    { 
     get 
     { 
      if (editCommand == null) 
      { 
       editCommand = new ViewCommand(param => this.EditEmployee()); 
      } 
      return editCommand; 
     } 
    } 

    private void EditEmployee() 
    { 
     NavigationActions.OpenEmployeeView(SelectedEmployee); 
    } 

    /// <summary> 
    /// save command 
    /// </summary> 
    private ViewCommand saveCommand; 
    public ViewCommand SaveCommand 
    { 
     get 
     { 
      if (saveCommand == null) 
      { 
       saveCommand = new ViewCommand(
         param => this.SaveEmployee(), 
         param => this.CanSaveEmployee 
         ); 
      } 
      return saveCommand; 
     } 
    } 

    public void SaveEmployee() 
    { 
     employeeRpository.SaveChanges(); 
    } 

    private bool CanSaveEmployee 
    { 
     get { return true; } 
    } 

    /// <summary> 
    /// clear search command 
    /// </summary> 
    private ViewCommand clearSearchCommand; 
    public ViewCommand ClearSearchCommand 
    { 
     get 
     { 
      if (clearSearchCommand == null) 
       clearSearchCommand = new ViewCommand(param => this.ClearSearch()); 
      return clearSearchCommand; 
     } 
    } 

    private void ClearSearch() 
    { 
     this.SearchText = string.Empty; 
     ListOfEmployees = new ObservableCollection<EmployeeDto>(employeeRpository.GetEmployees(true)); 
    } 

    /// <summary> 
    /// search command 
    /// </summary> 
    private ViewCommand searchCommand; 
    public ViewCommand SearchCommand 
    { 
     get 
     { 
      if (searchCommand == null) 
       searchCommand = new ViewCommand(param => this.SearchEmployee()); 
      return searchCommand; 
     } 
    } 

    private void SearchEmployee() 
    { 
     if (this.SearchText == string.Empty || this.SearchText == null) 
     { 
      NavigationActions.ShowError("Search Employees.", "Please enter your search text ..."); 
      return; 
     } 
     ListOfEmployees = new ObservableCollection<EmployeeDto>(employeeRpository.GetEmployeesByQuery(SearchText, Location)); 
    } 

    /// <summary> 
    /// exit command 
    /// </summary> 
    private ViewCommand exitCommand; 
    public ViewCommand ExitCommand 
    { 
     get 
     { 
      if (exitCommand == null) 
      { 
       exitCommand = new ViewCommand(param => this.ExitWindow()); 
      } 
      return exitCommand; 
     } 
    } 

    private void ExitWindow() 
    { 
     NavigationActions.CloseCurrentView(); 
    } 
    #endregion 


    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 

    #endregion 
    } 
} 

<Window x:Class="Attendance.Views.EmployeeSelectView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vm="clr-namespace:Attendance.ViewModels" 
    Title="Employee Maintenance" FocusManager.FocusedElement="{Binding ElementName=txtSearchCriteria}" 
    Height="525" Width="800" WindowStartupLocation="CenterScreen" WindowState="Normal" 
    WindowStyle="SingleBorderWindow" Icon="Images/gb_icon.png"> 
<Window.DataContext> 
    <vm:EmployeeSelectViewModel /> 
</Window.DataContext> 
<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="Themes/DataGrid.Generic.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
     <!--xml data start--> 
     <XmlDataProvider x:Key="LocationData" XPath="LocationList/LocationItem" Source="XMLData/Location.xml"/> 
     <!--xml data end--> 
    </ResourceDictionary> 
</Window.Resources> 
<Grid Width="775"> 
    <DockPanel HorizontalAlignment="Left" Width="770"> 
     <!-- TOOLBAR --> 
     <DockPanel DockPanel.Dock="Top" MinHeight="30" Margin="5"> 
      <ToolBar FontWeight="Bold"> 
       <!-- NEW --> 
       <Button Name="btnNew" Command="{Binding Path=NewCommand}"> 
        <Button.ToolTip> 
         <StackPanel> 
          <Label FontWeight="Bold" Background="SteelBlue" Foreground="White"> 
           Create a new Customer 
          </Label> 
          <TextBlock Padding="10" TextWrapping="WrapWithOverflow" Width="200"> 
          Create a new customer in a new Window tab. 
          </TextBlock> 
          <Line Stroke="SteelBlue" StrokeThickness="1" X2="200" /> 
          <StackPanel Orientation="Horizontal"> 
           <Image Margin="2" Source="Images/new.png"/> 
           <Label>Press F1 for more help</Label> 
          </StackPanel> 
         </StackPanel> 
        </Button.ToolTip> 
        <StackPanel Orientation="Horizontal"> 
         <Image Source="Images/new.png" Width="22" Height="22" Margin="2"/> 
         <Label VerticalAlignment="Center">_New</Label> 
        </StackPanel> 
       </Button> 
       <!-- EDIT --> 
       <Button Name="btnEdit" Command="{Binding Path=EditCommand}"> 
        <Button.ToolTip> 
         <StackPanel> 
          <Label FontWeight="Bold" Background="SteelBlue" Foreground="White"> 
           Edit the current record 
          </Label> 
          <TextBlock Padding="10" TextWrapping="WrapWithOverflow" Width="200"> 
          Edit the current selected Customer. 
          </TextBlock> 
          <Line Stroke="SteelBlue" StrokeThickness="1" X2="200" /> 
          <StackPanel Orientation="Horizontal"> 
           <Image Margin="2" Source="Images/dialog-information.png"/> 
           <Label>Press F1 for more help</Label> 
          </StackPanel> 
         </StackPanel> 
        </Button.ToolTip> 

        <StackPanel Orientation="Horizontal"> 
         <Image Source="Images/edit.png" Width="22" Height="22" Margin="2" /> 
         <Label VerticalAlignment="Center">_Edit</Label> 
        </StackPanel> 
       </Button> 
       <!-- SEARCH --> 
       <Separator /> 
       <TextBox Name="txtSearchCriteria" 
        MinWidth="300" Margin="5" 
        BorderThickness="1" BorderBrush="LightGray" 
        FontWeight="Normal" Foreground="Gray" Text="{Binding Path=SearchText}"> 
       </TextBox> 
       <Button Name="btnSearch" Command="{Binding Path=SearchCommand}"> 
        <Button.ToolTip> 
         <StackPanel> 
          <Label FontWeight="Bold" Background="SteelBlue" Foreground="White"> 
           Search 
          </Label> 
          <TextBlock Padding="10" TextWrapping="WrapWithOverflow" Width="200"> 
          Search a specific Customer. 
          </TextBlock> 
          <Line Stroke="SteelBlue" StrokeThickness="1" X2="200" /> 
          <StackPanel Orientation="Horizontal"> 
           <Image Margin="2" Source="Images/find.png"/> 
           <Label>Press F1 for more help</Label> 
          </StackPanel> 
         </StackPanel> 
        </Button.ToolTip> 
        <StackPanel Orientation="Horizontal"> 
         <Image Source="Images/find.png" Width="22" Height="22" Margin="2" /> 
         <Label VerticalAlignment="Center">_Find</Label> 
        </StackPanel> 
       </Button> 
       <Button Name="btnClearSearch" Command="{Binding Path=ClearSearchCommand}"> 
        <Button.ToolTip> 
         <StackPanel> 
          <Label FontWeight="Bold" Background="SteelBlue" Foreground="White"> 
           Search 
          </Label> 
          <TextBlock Padding="10" TextWrapping="WrapWithOverflow" Width="200"> 
          Clear search results. 
          </TextBlock> 
          <Line Stroke="SteelBlue" StrokeThickness="1" X2="200" /> 
          <StackPanel Orientation="Horizontal"> 
           <Image Margin="2" Source="Images/find.png"/> 
           <Label>Press F1 for more help</Label> 
          </StackPanel> 
         </StackPanel> 
        </Button.ToolTip> 
        <StackPanel Orientation="Horizontal"> 
         <Label VerticalAlignment="Center">_Clear Search</Label> 
        </StackPanel> 
       </Button> 
       <!-- EXIT --> 
       <Separator /> 
       <Button Name="btnExit" Command="{Binding Path=ExitCommand}"> 
        <Button.ToolTip> 
         <StackPanel> 
          <Label FontWeight="Bold" Background="SteelBlue" Foreground="White"> 
           Start the application 
          </Label> 
          <TextBlock Padding="10" TextWrapping="WrapWithOverflow" Width="200"> 
          Start the main application with the M-V-MV pattern. 
          </TextBlock> 
          <Line Stroke="SteelBlue" StrokeThickness="1" X2="200" /> 
          <StackPanel Orientation="Horizontal"> 
           <Image Margin="2" Source="Images/dialog-information.png"/> 
           <Label>Press F1 for more help</Label> 
          </StackPanel> 
         </StackPanel> 
        </Button.ToolTip> 

        <StackPanel Orientation="Horizontal"> 
         <Image Source="Images/exit.png" Width="22" Height="22" Margin="2" /> 
         <Label VerticalAlignment="Center">_Exit</Label> 
        </StackPanel> 
       </Button> 
      </ToolBar> 
     </DockPanel> 
     <!-- LIST --> 
     <DockPanel DockPanel.Dock="Top" MinHeight="30" Margin="0,0,0,5"> 
      <Label>Location:</Label> 
      <ComboBox Name="cboLocation" Grid.Column="1" Grid.Row="4" 
           ItemsSource="{Binding Source={StaticResource LocationData}}" 
           DisplayMemberPath="location_text" SelectedValuePath="location_value" 
           SelectedValue="{Binding Path=Location}" 
           HorizontalAlignment="Left" Width="175" Margin="4" /> 
     </DockPanel> 
     <DockPanel Margin="5"> 
      <DataGrid ItemsSource="{Binding Path=ListOfEmployees}" AutoGenerateColumns="False" IsReadOnly="True" 
       Name="dgEmployee" SelectionMode="Single" SelectionUnit="FullRow" CanUserResizeColumns="True" 
       SelectedItem="{Binding Path=SelectedEmployee}" GridLinesVisibility="Horizontal"> 
       <DataGrid.Columns> 
        <DataGridTextColumn Header="Employee ID" Width="SizeToCells" MinWidth="125" Binding="{Binding EmployeeID}" /> 
        <DataGridTextColumn Header="First Name" Width="SizeToCells" MinWidth="200" Binding="{Binding FirstName}" /> 
        <DataGridTextColumn Header="Last Name" Width="SizeToCells" MinWidth="200" Binding="{Binding LastName}" /> 
        <DataGridTextColumn Header="Location" Width="SizeToCells" MinWidth="125" Binding="{Binding Location}" /> 
        <DataGridCheckBoxColumn x:Name="Active" Header="Active" Binding="{Binding active}" MinWidth="75" /> 
       </DataGrid.Columns> 
      </DataGrid> 
     </DockPanel> 
    </DockPanel> 
</Grid> 

回答

1

你以前的代碼應該也可以工作,但'魔術串'阻礙了你。 屬性名稱爲ListOfEmployees,並在其setter中引發屬性名稱爲ListOfEmployee的PropertyChanged事件。 's'缺失。

當心你的新代碼。它會在每次插入時在ListOfEmployees上引發CollectionChanged事件,並且如果您正在進行多次插入,這可能會使您的應用程序變得更慢。 對於許多插入,最好從ObservableCollection派生並實現Reset方法,該方法清除基礎項目,添加新項目並引發類型爲Reset的CollectionChanged事件。

1

我的問題得到回答在其他網站上的帖子。相反,在我看來模型創建ListOfEmployees的新實例,我剛剛清除現有的一個,並添加從我的庫中的結果:

 private void SearchEmployee() 
    { 
     if (String.IsNullOrEmpty(this.SearchText) || String.IsNullOrEmpty(this.Location)) 
     { 
      NavigationActions.ShowError("Search Employees.", "Please enter your search text and select a location..."); 
      return; 
     } 

     // clear the list and repopulate based on the search criteria 
     if (ListOfEmployees != null) 
     { 
      ListOfEmployees.Clear(); 

      IList<EmployeeDto> iList = employeeRpository.GetEmployeesByQuery(SearchText, Location, IsActive); 
      foreach (EmployeeDto value in iList) 
       ListOfEmployees.Add(value); 
     } 
    } 

該訣竅。

1

這是我的解決方案:

<DataGrid Name="dgrid" ItemsSource="{Binding UserSettings, IsAsync=True}" AutoGenerateColumns="False"> 

的關鍵是IsAsync =真的設置,允許發生

屏幕漆