C#滚动列表视图到更新的项目

C#滚动列表视图到更新的项目,c#,wpf,C#,Wpf,我有一个列表视图 <ListView x:Name="BlockList" Grid.Row="1" Grid.ColumnSpan="4" ItemsSource="{Binding Blocks}"> <ListView.View> <GridView> <GridViewColumn Width="75" Header="Address" DisplayMemberBi

我有一个
列表视图

    <ListView x:Name="BlockList" Grid.Row="1" Grid.ColumnSpan="4" ItemsSource="{Binding Blocks}">
        <ListView.View>
            <GridView>
                <GridViewColumn Width="75" Header="Address" DisplayMemberBinding="{Binding Path=Address, Converter={StaticResource IntToHexConverter}}"/>
                <GridViewColumn Width="100" Header="Length" DisplayMemberBinding="{Binding Length}"/>
                <GridViewColumn Width="100" Header="Status" DisplayMemberBinding="{Binding Status}"/>
            </GridView>
        </ListView.View>
    </ListView>
这些
最初将以
块状态开始。未写入
状态,最终被
写入
,然后被
验证
。当
状态更改时,如何将
列表视图
滚动到


有很多事情需要做

1) 您的
需要实现
INotifyPropertyChanged

public class Block : ObservableObject, INotifyPropertyChanged
{
    // Your existing members and code


    private BlockStatus _status;
    public BlockStatus Status
    {
        get { return _status; }
        set { _status = value; NotifyPropertyChanged("Status"); }
    }

    // INotifyPropertyChanged implementation
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
2) 您的
ViewModel
需要有一个
StatusChanged
事件

public delegate void StatusChangedHandler(object sender, StatusChangedHandlerArgs args);
public event StatusChangedHandler StatusChanged;

// Put this class where it suits your project
public class StatusChangedHandlerArgs
{
    public Block.BlockStatus NewStatus { get; private set; }

    public StatusChangedHandlerArgs(Block.BlockStatus newStatus)
    {
        NewStatus = newStatus;
    }
}
3)
视图模型中的
属性需要如下所示:

    private ObservableCollection<Block> _blocks;
    public ObservableCollection<Block> Blocks
    {
        get
        {
            return _blocks;
        }
        set
        {
            _blocks = value;
            if (_blocks != null)
            {
                foreach (var block in _blocks)
                {
                    block.PropertyChanged += block_PropertyChanged;
                }
            }
            NotifyPropertyChanged("Blocks");
        }
    }

   // The event handler for PropertyChanged 
    private void block_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName != "Status" || StatusChanged == null)
        {
            return;
        }

        var block = sender as Block;
        if (block != null)
        {
            StatusChanged.Invoke(block, new StatusChangedHandlerArgs(block.Status));
        }
    }

这听起来有点像一个丑陋的解决方案。糟糕的用户体验。用户应该可以不间断地自由滚动,我建议在状态栏中显示最新的状态更新。或者只在写入项目后将其添加到列表框中,每次添加新项目时滚动到底。Glen他的项目有什么不好的地方不由你来决定。将列表项自动滚动到视图中是完全合理的。
    private ObservableCollection<Block> _blocks;
    public ObservableCollection<Block> Blocks
    {
        get
        {
            return _blocks;
        }
        set
        {
            _blocks = value;
            if (_blocks != null)
            {
                foreach (var block in _blocks)
                {
                    block.PropertyChanged += block_PropertyChanged;
                }
            }
            NotifyPropertyChanged("Blocks");
        }
    }

   // The event handler for PropertyChanged 
    private void block_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName != "Status" || StatusChanged == null)
        {
            return;
        }

        var block = sender as Block;
        if (block != null)
        {
            StatusChanged.Invoke(block, new StatusChangedHandlerArgs(block.Status));
        }
    }
   // Somewhere in the initializer or constructor for the page
   yourViewModel.StatusChanged += yourViewModel_StatusChanged;

   // The handler for StatusChanged
   private void yourViewModel_StatusChanged(object sender, StatusChangedHandlerArgs args)
    {
        var block = sender as Block;
        if (block != null)
        {
            BlockList.ScrollIntoView(block);
        }
    }