Focus does not “hold” when the list is updated

I currently have a problem with my code, where there will be no focus on a particular line of the element. I created int focusReferenceto track the current focused line, but every couple of seconds it is displayed as reset to 0, that is, as soon as the user selects the line, after a couple of seconds he "forgets" the users selection. I gave an example below:

enter image description here

enter image description here

As you can see from my code below, I have a timer doing something every few seconds. I have already been told that updating my list every few seconds leads to a loss of focus every few seconds.

, , ? FocusItem, , , . , , , (, , ) :

public MainWindow()
{
    InitializeComponent();
    int focusReference = 0;
    PlotListView.SelectionChanged += (s, ee) => { PlotListView_SelectionChanged(s, ee, focusReference); };
    var dbObject = new DbConnect();
    dbObject.OpenConnection();
    RefreshPlotTimer(filterReference, focusReference);
}

public void PlotListView_SelectionChanged(object sender, SelectionChangedEventArgs e, int focusReference)
{
    if (PlotListView.SelectedItems.Count == 0) return;
    var selectedItem = (DbConnect.PlotList)PlotListView.SelectedItems[0];
    focusReference = Convert.ToInt32(selectedItem.PlotId);
    FocusItem(focusReference);
}

private void FocusItem(int focusReference)
{
    if (PlotListView.SelectedItems.Count != 0)
    {
        DbConnect.PlotList plotList =
            PlotListView.Items.OfType<DbConnect.PlotList>()
            .FirstOrDefault(p => Convert.ToInt32(p.PlotId) == focusReference);
        if (plotList != null)
        {
            //get visual container
            var container = PlotListView.ItemContainerGenerator.ContainerFromItem(plotList) as ListViewItem;
            if (container != null)
            {
                container.IsSelected = true;
                container.Focus();
            }
        }
    }
}

public void RefreshPlotTimer(int filterReference, int focusReference)
{
    var refreshTimer = new Timer();
    refreshTimer.Elapsed += (sender, e) => RefreshPlot(sender, e, filterReference, focusReference);
    refreshTimer.Interval = 2500;
    refreshTimer.Enabled = true;
}

public void RefreshPlot(object source, ElapsedEventArgs e, int filterReference, int focusReference)
{
    var dbObject = new DbConnect();
    dbObject.OpenConnection();
    dbObject.RefreshPlot();
    Dispatcher.Invoke(() =>
    {
        FocusItem(focusReference);
        if (!string.IsNullOrWhiteSpace(FilterTextBox.Text) &&
            (!Regex.IsMatch(FilterTextBox.Text, "[^0-9]")))
        {
            filterReference = Convert.ToInt32(FilterTextBox.Text);
        }
    });
    ResetPlot(filterReference);
}

public void ResetPlot(int filterReference)
{
    var dbObject = new DbConnect();
    dbObject.OpenConnection();

    List<DbConnect.PlotList> plotList = dbObject.SelectPlotLists(filterReference);
    Dispatcher.BeginInvoke(
        new ThreadStart(() => PlotListView.ItemsSource = plotList));
    int jobSum = 0;
    int bidSum = 0;
    foreach (DbConnect.PlotList item in PlotListView.Items)
    {
        jobSum += Convert.ToInt32(item.Jobs);
        bidSum += Convert.ToInt32(item.Bids);
    }

    Dispatcher.BeginInvoke(
        new ThreadStart(() => JobBidRatioTextBlock.Text = jobSum + " jobs - " + bidSum + " bids"));
}

2

, , , FocusItem ?

private void FocusItem(int focusReference)
{
    Dispatcher.Invoke(() =>
    {
        if (PlotListView.SelectedItems.Count != 0)
        {
            DbConnect.PlotList plotList =
                PlotListView.Items.OfType<DbConnect.PlotList>()
                    .FirstOrDefault(p => Convert.ToInt32(p.PlotId) == focusReference);
            if (plotList != null)
            {
                //get visual container
                var container = PlotListView.ItemContainerGenerator.ContainerFromItem(plotList) as ListViewItem;
                if (container != null)
                {
                    container.IsSelected = true;
                    container.Focus();
                }
            }
        }
    }
}

, , , .

PlotListView_SelectionChanged 4
Before refresh 4
After refresh 4
PlotListView_SelectionChanged 7
Before refresh 7
After refresh 7

Before refresh 7
After refresh 7

refresh plot...

public void RefreshPlot(object source, ElapsedEventArgs e)
{
    var dbObject = new DbConnect();
    dbObject.OpenConnection();
    dbObject.RefreshPlot();
    Console.WriteLine("\rBefore refresh " + focusReference);
    Dispatcher.Invoke(() =>
    {
        if (!string.IsNullOrWhiteSpace(FilterTextBox.Text) &&
            (!Regex.IsMatch(FilterTextBox.Text, "[^0-9]")))
        {
            filterReference = Convert.ToInt32(FilterTextBox.Text);
        }
    });
    ResetPlot(filterReference);
    Console.WriteLine("After refresh " + focusReference);
    FocusItem(focusReference);
}

reset...

public void ResetPlot(int filterReference)
{
    // Establish MySQL connection
    var dbObject = new DbConnect();
    dbObject.OpenConnection();

    // Fill plot list view
    List<DbConnect.PlotList> plotList = dbObject.SelectPlotLists(filterReference);
    Dispatcher.BeginInvoke(
        new ThreadStart(() => PlotListView.ItemsSource = plotList));
    int jobSum = 0;
    int bidSum = 0;
    foreach (DbConnect.PlotList item in PlotListView.Items)
    {
        jobSum += Convert.ToInt32(item.Jobs);
        bidSum += Convert.ToInt32(item.Bids);
    }
    FocusItem(focusReference);

    // Determine job/bid list ratio
    Dispatcher.BeginInvoke(
        new ThreadStart(() => JobBidRatioTextBlock.Text = jobSum + " jobs - " + bidSum + " bids"));
}
+4
1

SelectedItem . .

, , ( ), SelectedItem.

- SelectedIndex, , , , .

// Gets current selection.
public DbConnect.PlotList SelectedPlotList
{
    get
    {
        return PlotListView.SelectedItem as DbConnect.PlotList;
    }
}
public void ResetPlot(int filterReference)
{
    // Get current plot number;
    int? plotNumber = SelectedPlotList == null ? (int?)null : SelectedPlotList.PlotNumber;

    var dbObject = new DbConnect();
    dbObject.OpenConnection();

    List<DbConnect.PlotList> plotList = dbObject.SelectPlotLists(filterReference);

    // Find the plot list in the new list.  
    DbConnect.PlotList selectPlotList = 
        plotNumber.HasValue
        ? plotList.Where(x => x.PlotNumber == plotNumber.Value).FirstOrDefault();
        : null;
    Dispatcher.BeginInvoke(new ThreadStart(() => PlotListView.ItemsSource = plotList));

    // Re-select plot list if found in the new list.
    if (selectPlotList != null)
    {
        PlotListView.SelectedItem = selectPlotList;
    }
    int jobSum = 0;
    int bidSum = 0;


    foreach (DbConnect.PlotList item in PlotListView.Items)
    {
        jobSum += Convert.ToInt32(item.Jobs);
        bidSum += Convert.ToInt32(item.Bids);
    }

    Dispatcher.BeginInvoke(
        new ThreadStart(() => JobBidRatioTextBlock.Text = jobSum + " jobs - " + bidSum + " bids"));
}

EDIT:

, . .

7 , :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        List<ListViewItem> items = new List<ListViewItem>();
        Random rnd = new Random(DateTime.Now.Millisecond);
        HashSet<int> ids = new HashSet<int>();
        for (int i = 0; i < 7; i++)
        {
            int id = 0;
            do
            {
                id = rnd.Next(0, 10);
            } while (ids.Contains(id));
            ids.Add(id);
            items.Add(new ListViewItem() { Id = id, Name = "Item-" + i });
        }
        int? selectedId = listView1.SelectedItem != null ? (listView1.SelectedItem as ListViewItem).Id : (int?)null;
        listView1.ItemsSource = items;

        if (selectedId.HasValue)
        {
            listView1.SelectedItem = items.Where(x => x.Id == selectedId).FirstOrDefault();
            listView1.Focus();
        }
    }
}

class ListViewItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}
+2

All Articles