繁体   English   中英

如何在不闪烁的情况下更新ComboBox ItemsSource

[英]How to Update ComboBox ItemsSource Without Flickering

我正在努力对以前可以使用的ComboBox进行更新。 我最初将其ItemsSource绑定到ViewModel中的只读ObservableCollection<char>属性。 当用户发起更改时(通过鼠标笔划完成更改,在某些情况下,每秒执行数十次),get会从Model重建集合并返回它。

当我在ObservableCollection更改为自己的对象时, ComboBox在更新期间开始闪烁。 我不知道怎么了。 这是从XAML开始的有效代码:

<ComboBox ItemsSource='{Binding FromBins}' SelectedValue='{Binding SelectedFromBin, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}' />

视图模型:

public ObservableCollection<char> FromBins
    {
        get
        {
            ObservableCollection<char> tempBins = new ObservableCollection<char>();
            foreach (var item in Map.BinCounts)
            {
                tempBins.Add(item.Key);
            }
            return tempBins;
        }
    }

我只是在每次鼠标移动时都进行了属性更改,并且界面按预期工作(存在其他逻辑来确保SelectedItem有效)。

为了使界面更有用,我决定使用自己的类向ComboBox添加更多信息:

public class BinItem : IEquatable<BinItem>
{
    public char Bin { get; set; }
    public SolidColorBrush BinColor { get; set; }
    public string BinColorToolTip { get {...} }

    public BinItem( char bin )
    {
        Bin = bin;
        BinColor = new SolidColorBrush(BinColors.GetBinColor(bin));
    }

    public bool Equals(BinItem other)
    {
        return other.Bin == Bin ? true : false;
    }
}

如果我在工作代码ViewModel BinItem char换为BinItem ,则在移动鼠标时会闪烁。 这是更新的XAML:

<ComboBox ItemsSource='{Binding FromBins}' SelectedValue='{Binding SelectedFromBin, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}'>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" ToolTip='{Binding BinColorToolTip}'>
                <Rectangle Fill='{Binding BinColor}' Width='10' Height='10' HorizontalAlignment='Center' VerticalAlignment='Center' Margin='0,0,4,0' Stroke='#FF747474' />
                    <TextBlock Text="{Binding Bin}" Width='16' />
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

我已经尝试了很多方法,包括但不限于:-使用List而不是ObservableCollection但是即使Get每次都触发并返回正确的项目集合,接口也不会总是更新(尽管闪烁消失了)。 -将所有可能的垃圾箱留在项源中,并将Visibility属性添加到绑定到的BinItem类中(无法更新)。

我怀疑我做的事情根本上是错误的,但是到目前为止,搜索SO或其他方式均无济于事。 任何帮助表示赞赏。

我能够使用Clemens和Chris的想法解决这个问题。 不确定这是否是最优雅的解决方案,但它是否按预期工作,而性能却没有明显下降。

我没有通过每次刷新替换集合的方法,而是通过逻辑来找出更改的内容(每次更新都可以同时添加和删除)。 代码如下:

private ObservableCollection<BinItem> _FromBins = new ObservableCollection<BinItem>();

public ObservableCollection<BinItem> FromBins
{
    get
    {
        if (_FromBins.Count > 0)
        {
            List<char> BinsToRemove = new List<char>();
            foreach (var item in _FromBins)
            {
                if (!Map.BinCounts.ContainsKey(item.Bin))
                {
                    BinsToRemove.Add(item.Bin);
                }
            } 
            foreach (var item in BinsToRemove)
            {
                _FromBins.Remove(new BinItem(item));
            }
        }
        foreach (var item in Map.BinCounts)
        {
            if (!_FromBins.Contains(new BinItem(item.Key)) && item.Value > 0)                   {
                _FromBins.Add(new BinItem(item.Key));
            }
        }
        return _FromBins;
    }
}

希望这也可以帮助其他人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM