我有一个绑定到ObservableList的组合框(可观察列表继承自ObservableCollection)。这是我的Carrier对象:
public class Carrier
{
/// <summary>
/// The carrier's name as it should be displayed to customers
/// </summary>
public string Name { get; set; }
/// <summary>
/// This is the domain that email-to-text messages should be sent to.
/// </summary>
public string TextBase { get; set; }
/// <summary>
/// Unique identifier for carriers
/// </summary>
public int CarrierId { get; set; }
}
我的问题是,在我的ViewModel中,我试图设置所选项的值,而不是在UI中设置它。当我从组合框中选择一个选项时,它正在正确地修改我的viewmodel(所以我知道绑定工作正常)。
这是我的xaml:
<ComboBox ItemsSource="{Binding ElementName=UserInformationPage, Path=DataContext.PhoneCarriers}"
Style="{StaticResource ComboBox}"
Width="250"
DisplayMemberPath="Name"
SelectedItem="{Binding Path=SelectedCarrier, Mode=TwoWay}"
SelectedValuePath="CarrierId"
/>
这是我的viewmodel:
public Carrier SelectedCarrier
{
get { return _selectedCarrier != null ? PhoneCarriers.First(c => c.CarrierId == _selectedCarrier.CarrierId) : PhoneCarriers.First(); }
set
{
if (_selectedCarrier == null || _selectedCarrier.CarrierId != value.CarrierId)
{
Set(ref _selectedCarrier, value);
if (User != null)
User.Phone.Carrier = value;
}
}
}
public UserDemographicsViewModel()
{
MessengerInstance.Register<SelectedUser>(this, m =>
{
User = m.User;
CheckCanShowPassword();
CheckCanResetPassword();
});
NavigationService.Navigated += (s, e) =>
{
if (e.Parameter is User)
{
User = e.Parameter as User;
if (User.Phone != null)
{
SelectedCarrier = User.Phone.Carrier;
}
}
};
IsPasswordTextShown = false;
TogglePasswordCommand = new RelayCommand(() => IsPasswordTextShown = !IsPasswordTextShown); //flip the state of password shown
SaveUserCommand = new RelayCommand<User>(SaveUser, u => CanSaveUser());
ResetPasswordCommand = new RelayCommand(TryResetPassword, () => User != null && User.UserId != 0); //we have a user and its not a new user
var repo = IoCContainer.GetContainer().Resolve<IAccountRepository>();
var loggedInUser = App.Session.Get<User>("AuthenticatedUser");
PhoneCarriers = new ObservableList<Carrier>(repo.GetPhoneCarriers(loggedInUser.AccountId));
}
正如我所说的,我知道我被绑定到SelectedCarrier属性,但由于某种原因,当SelectedCarrier与PhoneCarriers集合中的值匹配时,下拉列表显示为空白。
更新
我尝试使用以下内容简化我的SelectedCarrier属性:
public Carrier SelectedCarrier
{
get { return _selectedCarrier; }
set
{
if (_selectedCarrier == null || _selectedCarrier.CarrierId != value.CarrierId)
{
_selectedCarrier = value;
RaisePropertyChanged("SelectedCarrier");
if (User != null)
User.Phone.Carrier = value;
}
}
}
我知道我有一个选定的运营商,因为在调试时,如果我更改了下拉值,我可以看到_selectedCarrier的值在更改为新值之前(它可以很好地点击断点)。该值不会显示在用户界面中。
答案 0 :(得分:2)
所以问题与我的xaml有关,但我不确定为什么它不起作用。当我改变时:
<ComboBox ItemsSource="{Binding ElementName=UserInformationPage, Path=DataContext.PhoneCarriers}"
Style="{StaticResource ComboBox}"
Width="250"
DisplayMemberPath="Name"
SelectedItem="{Binding Path=SelectedCarrier, Mode=TwoWay}"
SelectedValuePath="CarrierId"
/>
为:
<ComboBox ItemsSource="{Binding PhoneCarriers}"
Style="{StaticResource ComboBox}"
Width="500"
SelectedValuePath="CarrierId"
DisplayMemberPath="Name"
SelectedItem="{Binding SelectedCarrier, Mode=TwoWay}"
/>
它开始在加载下拉列表中显示SelectedItem。
答案 1 :(得分:0)
我会尝试简化代码以查看它是否可以正常使用只使用支持字段而没有任何其他逻辑的简单属性。我假设您的Set()
方法可以很好地提出更改通知。
我怀疑你所设置的运营商与你所获得的运营商不同,我不知道绑定如何在内部运作的所有细节,但我怀疑这可能是一个问题如果你设置的与你刚刚获得的不一样。将断点放在setter和getter中,并确保绑定在设置后尝试获取新值。也许这些可能是不同的实例,但类型可能需要覆盖Equals()
和GetHashCode()
方法,因此来自不同来源的实例看起来相同。总的来说,将逻辑放入一个不仅仅是访问支持字段的可绑定属性getter是一个冒险的举动。