Подтвердить что ты не робот

Как вызвать TryUpdateModel вне метода обработки данных

  • VS2012,.NET 4.51

У меня есть пользовательский элемент управления, содержащий ListView, который использует привязку модели. Все идет нормально. Я хочу отобразить список объектов на основе того, как пользователь манипулировал режимом просмотра. Для этого у меня есть публичное свойство, называемое Ролями. Однако, когда я вызываю TryUpdateModel() изнутри, я получаю исключение:

TryUpdateModel 'должен быть передан провайдером значений или, альтернативно, должен быть вызван изнутри метода обработки данных элемента управления, который использует привязка модели для привязки данных

Теперь, когда я понимаю, что могу выйти из режима редактирования, сделав:

lvData.EditIndex = -1;

а затем в вызове UpdateMethod TryUpdateModel() мне было интересно, как я мог бы позвонить TryUpdateModel, не подключая метод для обновления. Иными словами, как/где/что я поставлю для параметра IValueProvider на TryUpdateModel().

/// <summary>
///     Initialise the user control
/// </summary>
/// <param name="aRoles">List of roles to display</param>
public void Activate(List<RoleInfo> aRoles)
{
    //List we will be binding
    _ViewModel = new List<MembershipRolesViewModel>();

    //Transfer the supplied list into the view model
    foreach (RoleInfo roleInfo in aRoles)
    {
        _ViewModel.Add(new MembershipRolesViewModel
        {
            RoleDisplayName = roleInfo.RoleDisplayName,
            RoleHint = roleInfo.RoleHint,
            RoleName = roleInfo.RoleName,
            RoleSelected = roleInfo.RoleSelected
        });
    }
}

//ListView.SelectMethod points here
public IQueryable<MembershipRolesViewModel> RolesSelect()
{
    return _ViewModel.AsQueryable();
}

//Property to return the roles as manipulated by the user
public List<RoleInfo> Roles
{
    get
    {
        List<RoleInfo> result = new List<RoleInfo>();
        TryUpdateModel(_ViewModel);

        foreach (MembershipRolesViewModel membershipRolesViewModel in _ViewModel)
        {
            result.Add(new RoleInfo
            {
                RoleDisplayName = membershipRolesViewModel.RoleDisplayName,
                RoleHint = membershipRolesViewModel.RoleHint,
                RoleName = membershipRolesViewModel.RoleName,
                RoleSelected = membershipRolesViewModel.RoleSelected
            });
        }

        return result;
    }
}

TryUpdateModel должен быть передан поставщик значений или, альтернативно, должен быть вызван изнутри метода обработки данных элемента управления, который использует привязку модели для привязки данных.

4b9b3361

Ответ 1

Нет простого способа получить значения из элементов ListView. Вы должны зацикливаться на элементах и ​​извлекать их значения.

var bindableTemplate = lv.ItemTemplate as IBindableTemplate;
foreach (ListViewItem item in lv.Items)
{
    var dic = bindableTemplate.ExtractValues(item).Cast<System.Collections.DictionaryEntry>().ToDictionary(k => (string)k.Key, v => v.Value);
    var provider = new DictionaryValueProvider<object>(dic, System.Globalization.CultureInfo.InvariantCulture);

    // Now we can update the item.
    TryUpdateModel<RoleInfo>(model, provider);
}

Или заставить ListView обновить собственный элемент.

public List<RoleInfo> Roles
{
    get
    {
        List<RoleInfo> result = new List<RoleInfo>();
        for (int i = 0; i < lv.Items.Count; i++)
            if (lv.Items[i].ItemType == ListViewItemType.DataItem)
                lv.UpdateItem(i, true);

        //...

        return result;
    }
}



public void lv_UpdateItem(int id)
{
    RoleInfo model = //...
    TryUpdateModel(model);
}

Надеюсь, что это поможет.

Ответ 2

Вызов TryUpdateModel за пределами метода действия, который является неправильным способом. Поскольку Model Binder тесно связан с методом Action, чтобы они могли автоматически заполнять свойства модели с данными, которые мы заполнили в пользовательском интерфейсе.

Итак, попробуйте TryUpdateModel в методе действий, надеюсь, что все будет хорошо.