Silverlight Combobox - Настройка выбранного элемента MVVM - PullRequest
1 голос
/ 11 апреля 2011

У меня есть ViewModel, которая устанавливает значение для свойства «UserStructure».Проблема в том, что выпадающий список не привязывается к значению.

public class OwnerOccupierAccountViewModel : ViewModelBase
{
    /// <summary>
    /// Load combobox structures
    /// </summary>
    private readonly LoadOperation<Structure> _loadStructures;

    private readonly LoadOperation<UnitOccupierDetail> _loadUnitOccupierDetails;

    //public ICommand SaveAccountSettingsCommand { get; set; }

    #region Properties

    private ObservableCollection<Structure> _structures;
    public ObservableCollection<Structure> Structures
    {
        get { return _structures; }

        set
        {
            _structures = value;
            RaisePropertyChanged("Structures");
        }
    }

    private Structure _userStructure;
    public Structure UserStructure
    {
        get { return _userStructure; }
        set
        {
            _userStructure = value;
            RaisePropertyChanged("SelectedStructure");
        }
    }

    private UnitOccupierDetail _unitOccupierDetail;
    public UnitOccupierDetail UnitOccupierDetail
    {
        get { return _unitOccupierDetail; }
        set
        {
            _unitOccupierDetail = value;
            RaisePropertyChanged("UnitOccupierDetail");
        }
    }


    #endregion

    public OwnerOccupierAccountViewModel()
    {
        // SaveAccountSettingsCommand = new DelegateCommand(SaveAccountSettings, CanSave);

        UserAccountContext _userAccountContext;

        if (!DesignerProperties.IsInDesignTool)
        {
            var loggedInUser = new Guid(WebContext.Current.User.UserID.ToString());

            _userAccountContext = new UserAccountContext();

            #region load structures
            _loadStructures = _userAccountContext.Load(_userAccountContext.GetStructuresQuery());
            _loadStructures.Completed += _loadStructuresCompleted;
            #endregion

            #region load user data 
            _loadUnitOccupierDetails =
                _userAccountContext.Load(
                    _userAccountContext.GetUnitOccupierDetailsQuery().Where(
                        u => u.UserIDFK == loggedInUser && u.StructureFK == 92));
            _loadUnitOccupierDetails.Completed += _loadUnitOccupierDetails_Completed;
            #endregion
        }
    }

    void _loadUnitOccupierDetails_Completed(object sender, EventArgs e)
    {
        _unitOccupierDetail= new UnitOccupierDetail();
        _unitOccupierDetail = _loadUnitOccupierDetails.Entities.First();

        _userStructure = _unitOccupierDetail.Structure;
    }

    void _loadStructuresCompleted(object sender, EventArgs e)
    {
        var theseStructures = new ObservableCollection<Structure>(_loadStructures.Entities);
        Structures = theseStructures;
    }

    //private void SaveAccountSettings(object param)
    //{

    //}

    //private static bool CanSave(object param)
    //{
    //    return true;
    //}
}

 <ComboBox x:Name="cboApartments" 
                          ItemsSource='{Binding Structures, Mode=TwoWay}'
                          DisplayMemberPath='StructureName'
                          SelectedValuePath='IDStructure'
                          SelectedItem='{Binding SelectedStructure,Mode=TwoWay}'
                          Width="200"
                          Height="25">

Ответы [ 3 ]

2 голосов
/ 11 апреля 2011

в xaml UserStructure вместо SelectedStructure.

0 голосов
/ 11 апреля 2011

В вашем XAML SelectedItem привязан к SelectedStructure вместо UserStructure, что вы хотите

ОБНОВЛЕНИЕ:

Ваш код не работает, поскольку вы должны установить объект SelectedItemкоторый имеет равенство ссылок с некоторым объектом в ItemsSource.В вашей ViewModel вы устанавливаете Structures как результат одной операции службы, а UserStructure - как результат другой.UserStructure и некоторые объекты в Structures могут быть равны (object.Equals), но не могут быть равными (object.ReferenceEquals).ComboBox, как и другие ItemsControls, не сравнивает элементы по равенству, он сравнивает их по идентичности.Итак, чтобы иметь правильный код, вы должны выбрать из объекта Structures, который равен UserStructure, и установить его как UserStructure:

   void _loadUnitOccupierDetails_Completed(object sender, EventArgs e)
   {
        ...

        Structure userStructure = Structures.FirstOrDefault(s=>s.Equals(_unitOccupierDetail.Structure));
        UserStructure = userStructure;
   }

В этом случае вы должны быть уверены, что Structures предшествует раньше.Вы можете посмотреть на метод Reactive Extensions Observable.ForkJoin (), чтобы синхронизировать 2 асинхронных вызова.

0 голосов
/ 11 апреля 2011

Попробуйте такие изменения

public class OwnerOccupierAccountViewModel : ViewModelBase
{
    /// <summary>
    /// Load combobox structures
    /// </summary>
    private readonly LoadOperation<Structure> _loadStructures;

    private readonly LoadOperation<UnitOccupierDetail> _loadUnitOccupierDetails;

    //public ICommand SaveAccountSettingsCommand { get; set; }

    #region Properties

    private ObservableCollection<Structure> _structures;
    public ObservableCollection<Structure> Structures
    {
        get { return _structures; }

        set
        {
            _structures = value;
            RaisePropertyChanged("Structures");
        }
    }

    private Structure _userStructure;
    public Structure UserStructure
    {
        get { return _userStructure; }
        set
        {
            _userStructure = value;
            RaisePropertyChanged("UserStructure");
        }
    }

    private UnitOccupierDetail _unitOccupierDetail;
    public UnitOccupierDetail UnitOccupierDetail
    {
        get { return _unitOccupierDetail; }
        set
        {
            _unitOccupierDetail = value;
            RaisePropertyChanged("UnitOccupierDetail");
        }
    }


    #endregion

    public OwnerOccupierAccountViewModel()
    {
        // SaveAccountSettingsCommand = new DelegateCommand(SaveAccountSettings, CanSave);

        UserAccountContext _userAccountContext;

        if (!DesignerProperties.IsInDesignTool)
        {
            var loggedInUser = new Guid(WebContext.Current.User.UserID.ToString());

            _userAccountContext = new UserAccountContext();

            #region load structures
            _loadStructures = _userAccountContext.Load(_userAccountContext.GetStructuresQuery());
            _loadStructures.Completed += _loadStructuresCompleted;
            #endregion

            #region load user data 
            _loadUnitOccupierDetails =
                _userAccountContext.Load(
                    _userAccountContext.GetUnitOccupierDetailsQuery().Where(
                        u => u.UserIDFK == loggedInUser && u.StructureFK == 92));
            _loadUnitOccupierDetails.Completed += _loadUnitOccupierDetails_Completed;
            #endregion
        }
    }

    void _loadUnitOccupierDetails_Completed(object sender, EventArgs e)
    {
        _unitOccupierDetail= new UnitOccupierDetail();
        _unitOccupierDetail = _loadUnitOccupierDetails.Entities.First();

        _userStructure = _unitOccupierDetail.Structure;
    }

    void _loadStructuresCompleted(object sender, EventArgs e)
    {
        var theseStructures = new ObservableCollection<Structure>(_loadStructures.Entities);
        Structures = theseStructures;
    }

    //private void SaveAccountSettings(object param)
    //{

    //}

    //private static bool CanSave(object param)
    //{
    //    return true;
    //}
}

 <ComboBox x:Name="cboApartments" 
                          ItemsSource='{Binding Structures, Mode=TwoWay}'
                          DisplayMemberPath='StructureName'
                          SelectedValuePath='IDStructure'
                          SelectedItem='{Binding UserStructure,Mode=TwoWay}'
                          Width="200"
                          Height="25">

Обновлен:

Хм, возможно попробуйте изменения здесь:

     <ComboBox x:Name="cboApartments" 
                              ItemsSource='{Binding Structures, Mode=TwoWay}'
                              SelectedItem='{Binding UserStructure, Mode=TwoWay}'
                              Width="200"
                              Height="25">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=StructureName}"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...