Silverlight Combobox - 设置SelectedItem MVVM

时间:2011-04-11 17:31:10

标签: silverlight silverlight-4.0 mvvm

我有一个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 个答案:

答案 0 :(得分:2)

在xaml UserStructure中而不是SelectedStructure。

答案 1 :(得分:0)

尝试此类更改

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>

答案 2 :(得分:0)

在你的XAML中,SelectedItem被绑定到SelectedStructure而不是UserStructure,你想要什么

<强>更新

您的代码不起作用,因为您应该设置为SelectedItem对象,该对象与ItemsSource中的某个对象具有引用相等性。在ViewModel中,将Structures设置为一个服务操作的结果,将UserStructure设置为另一个服务操作的结果。结构中的UserStructure和某个对象可以是equals(object.Equals)但不是引用equals(object.ReferenceEquals)。像其他ItemsControls一样,ComboBox不会通过相等比较项目,而是按身份比较它们。因此,要拥有正确的代码,您应该从结构对象中选择等于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个异步调用。