Silverlight组合框强制重新选择SelectedItem
我有一个绑定到ComboBox的项目列表。 当用户选择一个项目时,我想取消选择并选择其他项目。 这必须发生在SelectedItem绑定的属性的setter中。 我正在使用Silverlight 3。
我的ComboBox中每个项目的数据模型:
public class DataItem
{
public int Id { get; set; }
public string Name { get; set; }
}
设置为DataContext的对象:
public class DataContainer : INotifyPropertyChanged
{
public DataContainer()
{
itemList = new List<DataItem>();
itemList.Add(new DataItem() { Id = 1, Name = "First" });
itemList.Add(new DataItem() { Id = 2, Name = "Second" });
itemList.Add(new DataItem() { Id = 3, Name = "Third" });
}
public event PropertyChangedEventHandler PropertyChanged;
private DataItem selectedItem;
public DataItem SelectedItem
{
get { return selectedItem; }
set
{
if (value != null && value.Id == 2)
value = itemList[0];
selectedItem = value;
NotifyPropertyChanged("SelectedItem");
}
}
private List<DataItem> itemList;
public List<DataItem> ItemList
{
get { return itemList; }
set { itemList = value; NotifyPropertyChanged("DataList"); }
}
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
xaml的相关位:
<StackPanel>
<StackPanel Orientation="Horizontal">
<ComboBox x:Name="comboBox" DisplayMemberPath="Name" Width="100" ItemsSource="{Binding ItemList}" SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}"/>
<Button Content="Set to First" Width="100" Click="Button_Click"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Selected item: "/>
<TextBlock Text="{Binding SelectedItem.Id}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding SelectedItem.Name}"/>
</StackPanel>
</StackPanel>
它看起来像我的代码来选择第一个项目,当用户选择第二个项目正在工作。 被选择的项目实际上被设置为“第一”,而组合框仍然显示“第二”,就好像它被选中一样。
有什么办法强制ComboBox重绘或重新考虑它应该在视觉上标记为选中的内容吗?
我从上面提到的Button_Click方法这样做,它的工作原理:
private void Button_Click(object sender, RoutedEventArgs e)
{
var c = DataContext as DataContainer;
if (c != null)
{
c.SelectedItem = null;
c.SelectedItem = c.ItemList[0];
}
}
但设置为空,然后我想要的值不起作用,如果我从setter中执行它,就像我需要的那样。
我可能为你找到了一个解决方案。 通过执行以下操作,我能够得到我认为要求工作的内容:
public DataItem SelectedItem
{
get { return _selectedItem; }
set
{
if (value != null && value.Id == 2)
{
value = itemList[0];
UpdateUI(); // Call this to force the UI to update.
}
_selectedItem = value;
NotifyPropertyChanged("SelectedItem");
}
}
private void UpdateUI()
{
ThreadPool.QueueUserWorkItem(
o =>
{
Thread.Sleep(1);
Deployment.Current.Dispatcher.BeginInvoke(()=>
{
_selectedItem = null;
NotifyPropertyChanged("SelectedItem");
_selectedItem = itemList[0];
NotifyPropertyChanged("SelectedItem");
});
});
}
我希望我能向你解释为什么这个工作正常,但我只能猜测。 基本上,它退出UI线程,然后通过Dispatcher.BeginInvoke()调用稍后重新输入。 这似乎使ComboBox控制时间从用户交互中自行更新,然后响应分派器执行。
我发现的一个问题是,在多次执行线程代码之后,Silverlight似乎有些不可思议。 增加Thread.Sleep时间似乎有所帮助。 我认为这个解决方案适用于大多数情况,并不会成为问题。
你不必在1秒钟的时间内按照grimus的建议排队。 这应该也适用于你:
public DataItem SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
NotifyPropertyChanged("SelectedItem");
if (value != null && value.Id == 2)
{
Diployment.Current.Dispatcher.BeginInvoke(() => {
_selectedItem = itemList[0];
NotifyPropertyChanged("SelectedItem"); });
}
}
}
链接地址: http://www.djcxy.com/p/41259.html