Список объектов и кнопка - PullRequest
1 голос
/ 28 февраля 2012

Я новичок в MVVM.У меня есть список, который заполняет список сотрудников.Я использую MVVM light и Silverlight4

<ListBox BorderBrush="Transparent" 
         HorizontalContentAlignment="Stretch" 
         VerticalAlignment="Stretch" 
         Name="EmployeeListBox" 
         Background="Transparent" 
         ItemsSource="{Binding Employees}" 
         SelectedItem="{Binding SelectedEmployee, Mode=TwoWay}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid Margin="4">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="200"/>
                    <ColumnDefinition Width="200"/>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="300"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <sdk:Label Grid.Row="0" Grid.Column="0"
                    Content="Name" />
                <TextBox Grid.Column="1" Grid.Row="0"
                    Name="EmployeeName" 
                    Height="23" 
                    Text="{Binding Path=Name, Mode=TwoWay}" 
                    VerticalAlignment="Center" 
                    HorizontalAlignment="Stretch" />
                <Button Grid.Column="2" Grid.Row="0"
                    Name="RefresEmployeeName"  
                    Width="20" 
                    Height="25" 
                    Command="{Binding RefreshEmployeeNameCommand}"
                    Content="Refresh" />
                <Button Grid.Column="4" Grid.Row="0" 
                    Name="DeleteEmployee"
                    Width="20" 
                    Height="25" 
                    Content="Delete" 
                    Command="{Binding DeleteEmployeeCommand}" />
                <sdk:Label Grid.Row="1" Grid.Column="0"
                    Content="Description" />
                <TextBox Grid.Column="1" Grid.Row="1" Height="23" 
                    Text="Binding Path=Description}" 
                    VerticalAlignment="Center" 
                    HorizontalAlignment="Stretch" />
                <Button Grid.Column="2" Grid.Row="1"
                    Name="RefreshDescription"  
                    Width="20" 
                    Height="25" 
                    Content="Refresh" 
                    Command="RefreshDescriptionCommand" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

. Здесь отображается список сотрудников с именем и описанием, отображаемым в текстовых полях, и кнопкой «Обновить» рядом с текстовыми полями «Имя и описание сотрудника», а также кнопка «Удалить», расположенная спереди.Текстовое поле имени сотрудника.

В моей ViewModel я создал 3 RelayCommands как

RelayCommand RefreshEmployeeNameCommand = new RelayCommand(RefreshEmployeeName);
RelayCommand DeleteEmployeeCommand = new RelayCommand(DeleteEmployee);
RelayCommand RefreshDescriptionCommand = new RelayCommand(RefreshDescription);

Когда я нажимаю кнопку RefreshEmployeeName, содержимое в текстовом поле должно быть сброшено вего первоначальное значение, если были внесены какие-либо изменения в имя сотрудника.Когда я нажимаю кнопку DeleteEmployee, SelectedEmployee должен быть удален.Когда я нажимаю кнопку RefreshDescription, любые изменения в описании должны быть сброшены.

Когда я нажимаю RefreshEmployeeName, функция RefreshEmployeeName не вызывается во ViewModel.Как захватить данные в текстовое поле, связанное с этой кнопкой.А также, как захватить выбранный элемент при нажатии на кнопку.Выбранный элемент обновляется, когда я нажимаю рядом с границами.

Вот моя модель вида:

public IServiceAgent ServiceAgent { get; set; }

public EditViewModel(IServiceAgent serviceAgent)
{
    if (!IsDesignTime)
    {
        if (serviceAgent != null)
        {
            ServiceAgent = serviceAgent;
        }

        GetEmployees();
        WireCommands();
    }
}

private void WireCommands()
{
    RefreshEmployeeNameCommand = new RelayCommand(RefreshEmployeeName);
    DeleteEmployeeCommand = new RelayCommand(DeleteEmployee);
    RefreshEmployeeDescriptionCommand = new RelayCommand(RefreshEmployeeDescription);
}

public RelayCommand RefreshEmployeeNameCommand { get; private set; }

public RelayCommand DeleteEmployeeCommand { get; private set; }

public RelayCommand RefreshEmployeeDescriptionCommand { get; private set; }

private void RefreshEmployeeName()
{
    // have to capture the value within the textbox employee name
}

private void DeleteEmployee()
{
    // have to capture the employee object which should be deleted   
}

private void RefreshEmployeeDescription()
{
    // have to capture the value within the textbox employee description
}

private ObservableCollection<Employee> _Employees;
public ObservableCollection<Employee> Employees
{
    get
    {
        return _Employees
    }
    set
    {
        if _Employees!= value)
        {
            _Employees= value;
            OnPropertyChanged("Employees");
        }
    }
}

public Employee _SelectedEmployee;
public DisplayDevice SelectedEmployee
{
    get
    {
        return _SelectedEmployee;
    }
    set
    {
        if (_SelectedEmployee!= value)
        {
            _SelectedEmployee= value;
            OnPropertyChanged("SelectedEmployee");
        }
    }
}

private void GetEmployees()
{
    ServiceAgent.GetEmployees((s, e) => Employees = e.Result);
}

Ответы [ 3 ]

1 голос
/ 28 февраля 2012

Как догадка о том, что идет не так

Объекты внутри сотрудников (т.е. каждая строка) должны быть моделями представления с командами relay в них.

У вас может быть команда relay в главной модели представления, но она никогда не будет вызываться, потому что строки вашего списка связаны с элементами в Employees

0 голосов
/ 28 апреля 2012

Ваши команды не обрабатываются, потому что контекст данных для кнопок по умолчанию является сущностью Employee.Это связано с тем, что вы задали для ItemsSource свойство Employees в ViewModel, а затем каждая строка будет привязана к объекту сущности Employee.Следовательно, привязки команд ищут обработчики команд для объекта Employee, а не ViewModel.

Вам необходимо установить источник для команды так, чтобы он указывал на вашу модель представления, где существуют обработчики команд.Вот пример:

Command="{Binding Source={StaticResource ViewModel}, Path=RefreshEmployeeNameCommand}" 

" ViewModel " - это имя экземпляра EditViewModel, который был создан для представления.

0 голосов
/ 28 февраля 2012

Один из вариантов - иметь RelayCommand для каждого из ваших объектов Employee и связываться с ним. Таким образом, выполнение RelayCommand имеет весь контекст объекта, который ему необходим для выполнения.

Добавьте следующее к вашему объекту Employee:

public Employee : ViewModelBase
{
    public RelayCommand RefreshDescriptionCommand {get; private set}

    // ... 

    public Employee()
    {
         RefreshDescriptionCommand = new RefreshDescriptionCommand(RefreshDescription);

    //...

    private void RefreshDescription()
    {

         //Do whatever
    }
}

Ваши кнопки XAML должны быть привязаны к командам. Поскольку они находятся в шаблоне ItemsTemplate, они будут привязаны к RefreshDescriptionCommand для каждого из отдельных объектов Employee

<Button ...  Command="{Binding RefreshDescriptionCommand}" />

Когда ваша команда выполняется, она будет выполняться в контексте объекта, на котором была размещена кнопка, так что вы сможете обновить свои описания, обновить данные, что вам нужно сделать.

Вам нужно будет повторить эти шаги для каждой из ваших кнопок.

пара предостережений:

  1. Убедитесь, что ваш объект Employee реализует INotifyPropertyChanged (что он будет делать, если вы используете MVVM Light и наследует от ViewModelBase).

  2. Не помещайте это в ListBox. Это неправильный контроль за тем, что вы пытаетесь сделать. ItemsControl лучше подходит для этого. Единственное, что действительно дает ListBox - это возможность выбрать элемент, который не выглядит так, как вам нужно. Фактически, поведение при выборе элемента будет делать странные вещи с прокруткой и нажатием кнопки.

  3. Это, вероятно, самый простой способ сделать это в SilverLight. В WPF есть несколько других опций с привязкой к предку, но в SilverLight это сделать сложнее.

...