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

上一篇: Silverlight ComboBox force reselect SelectedItem

下一篇: combobox itemssource binding issue