обновить сетку данных при просмотре из viewmodel - PullRequest
3 голосов
/ 18 марта 2010

У меня есть сетка данных в представлении, которое связано с моделью представления. Когда я инициализирую представление, сетка данных заполняется данными из модели представления (ObservableCollection), как и должно быть. Однако при попытке поиска по данным сетка данных не обновляется из модели представления. Когда я устанавливаю точку останова в коде в моей модели представления, я вижу, что результаты в ObservableCollection изменились в моем поиске, но почему-то это не возвращается в представление. Вот мой вид и модель представления (кстати, я использую VS2010 RTM):

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>

Ответы [ 3 ]

3 голосов
/ 01 мая 2013

Это было мое решение:

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

Ключ, являющийся настройкой IsAsync = True, позволяет окраске экрана появляться

1 голос
/ 24 апреля 2012

Ваш предыдущий код тоже должен был сработать, но мешали «волшебные строки». Имя свойства - ListOfEmployees, и в его установщике вы вызываете событие PropertyChanged с именем свойства ListOfEmployee. 's' отсутствует.

Остерегайтесь вашего нового кода. Он будет вызывать событие CollectionChanged в ListOfEmployees для каждой вставки, и это может замедлить работу вашего приложения, если вы выполняете много вставок. Для многих вставок было бы лучше извлечь из ObservableCollection и реализовать метод Reset, который очищает базовые элементы, добавляет новые элементы и вызывает событие CollectionChanged типа Reset.

1 голос
/ 19 марта 2010

На мой вопрос ответили в сообщении на другом сайте.Вместо создания нового экземпляра 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);
        }
    }

Это помогло.

...