[英]Set the SelectionChanged event of a ComboBox while binding its SelectedItem and ItemsSource in XAML
[英]XAML WinRT ComboBox Set SelectedItem
我有一个绑定到ObservableList的组合框(observable列表继承自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中进行设置。 当我从组合框中选择一个选项时,它正在正确地修改我的视图模型(因此我知道绑定正在工作)。
这是我的xaml:
<ComboBox ItemsSource="{Binding ElementName=UserInformationPage, Path=DataContext.PhoneCarriers}"
Style="{StaticResource ComboBox}"
Width="250"
DisplayMemberPath="Name"
SelectedItem="{Binding Path=SelectedCarrier, Mode=TwoWay}"
SelectedValuePath="CarrierId"
/>
这是我的视图模型:
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的值更改为新值之前看到它的值(并且可以很好地达到断点)。 该值只是不显示在用户界面中。
因此,问题与我的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。
我将尝试简化代码,以查看其是否具有简单属性(仅使用备用字段而不使用任何其他逻辑)是否可以正常工作。 我假设您的Set()
方法可以很好地发出更改通知。
我怀疑您要设置的载体与您要获得的载体不同,并且我不知道绑定如何在内部工作的所有详细信息,但是我怀疑如果您要设置的载体可能会出现问题设置与您立即获得的设置不同。 将断点放在setter和getter中,并确保绑定在设置新值后尝试获取新值。 也许这些可能是不同的实例,但是类型可能需要重写Equals()
和GetHashCode()
方法,以便来自不同来源的实例看起来相同。 总的来说,将逻辑置于可绑定的属性获取器中,这不仅仅是简单地访问支持字段,这是一个冒险的举动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.