Set datagrid row background color WPF - Loop [closed]
Asked Answered
R

2

-3

I have one Task which go throw DataGridRow and do some task. When he finish it set background color for that row. I added cancel button to stop task, and continue button to continue where it finished last time. All work perfect except changing background color for row.

This is XAML code, i'm new to WPF so it's not too big for DataGrid

<DataGrid 
     Name="dataGridViewMyGroups" 
     Grid.Row="0" ColumnWidth="*" 
     VerticalScrollBarVisibility="Auto" 
     IsReadOnly="True" 
     SelectionUnit="FullRow" 
     SelectionMode="Single"    
     MouseDoubleClick="dataGridViewMyGroups_MouseDoubleClick">
</DataGrid>

Here is a C# code for changing background color.

DataGridRow rowColor = (DataGridRow)dataGridViewMyGroups.ItemContainerGenerator
                    .ContainerFromIndex(number);                                  
rowColor.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(223, 227, 238)); 

This code work when I click on start Button and it change Background color for each Row. Problem is when I click cancel Button and then click on continue Button, then I got NullReferenceException. Continue button only check last ID in DataBase Table.

int number=0;
foreach (GroupsInList group in dataGridViewMyGroups.Items)
{
   if (fbgroupID != null && check==true)
   {
       number++;
       if (fbgroupID != groupLink)
       {
         continue;
       }
       check = false;
       continue;
   }

     //Do something and change background (code above).
     number++;
}

Code for continue Button work except changing row's background.

UPDATE: Code for Cancel Button:

 if (MessageBox.Show("Do you want to stop posting?", "Confirmation", 
 MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
        {
            tokenSource.Cancel(); 
        }

Code for Continue Button:

        int postID;
        string fbGroupID;
        int listID;

        using (OleDbConnection connection = new OleDbConnection(conn))
        {

           //code for getting value from `DB Table`

            postID = list[0].PostID;
            fbGroupID = list[0].FBGroupID;
            listID = list[0].ListForGroupID;
        }

        cmbSelectList.SelectedValue = listID;
        cmbSavedPosts.SelectedValue = postID;
        loadGroupsInList(); //Maybe this is problem because here I update(reload) DataGrid again.

        tokenSource = new CancellationTokenSource();

        try
        {                              
            await TaskPostToGroup(tokenSource.Token, fbGroupID, true);
        }
        catch (OperationCanceledException ex)
        {
            System.Windows.MessageBox.Show(ex.Message, "CANCELED", MessageBoxButton.OK, MessageBoxImage.Stop);
        }
        catch (NullReferenceException)
        {
            //I don't have solution for changing background color for each row when continue button is clicked
        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show(ex.Message + "\n\n" + ex.StackTrace, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
        }
Roquefort answered 25/7, 2017 at 17:59 Comment(5)
Could you post your code in full - both your Cancel and Continue button code?Hildie
as I said problem isn't in cancel and in continue button code. because all work when I remove code lines for changing background. Cancel button only send Cancel Token Request. Continue as I wrote: get 3 strings for last ID in DB Table and call task with foreach loopRoquefort
That's not the point; I can't recreate your problem and/or try to figure out the problem without seeing the full picture. Your question is difficult to understand in the first place.Hildie
Where in the Continue button code are you calling the DataGrid row color change code? After loadGroupsInList()? Since you're getting a NullReferenceException, I'm guessing the datagrid doesn't have the row number you're specifying? Please debug your program and figure out which line throws the exception.Hildie
await TaskPostToGroup(tokenSource.Token, fbGroupID, true); is part of code where foreach loop executes and I have code for changing background color. In line for changing background color I get NullReferenceException . I have int number which increment at the end of foreach loop.Roquefort
R
-2

I resolved this problem. So the problem is because I fill DataGrid again with Data. Instead that I don't fill it I only get ID where I stopped from last time in that Table with some ID.

Code for Button Continue:

 int postID;
 string fbGroupID;
 int listID = int.Parse(cmbSelectList.SelectedValue.ToString());

 using (OleDbConnection connection = new OleDbConnection(conn))
 {

  ................

       commName.CommandText = "SELECT TOP 1 [FaceBookGroupID],[PostID] FROM [Advertiseing] WHERE [email] = @email AND [ListForGroupID]= @listID ORDER BY [Date-Time] DESC";

  ................

       postID = list[0].PostID;
       fbGroupID = list[0].FBGroupID;        
       *listID = list[0].ListForGroupID;* //Deleted
  }


  //cmbSelectList.SelectedValue = listID; - Deleted
    cmbSavedPosts.SelectedValue = postID;
  //loadGroupsInList(); - Deleted

  // Next part of code are the same
  ................
Roquefort answered 6/8, 2017 at 14:13 Comment(5)
-1 : None of this makes any sense. You're doing all of this wrong. Learn MVVM; do this properly and this question wouldn't even be needed. Even worse to offer bounty on your question and then award yourself the answer that doesn't actually answer.Decoy
I agree with Maverik, and also read this: link before posting a question next time. It will help you getting the information you need while also helping other people with similar problems. That's what Stack Overflow is all about ;)Euphemia
@Decoy I waiting too long for answer, and I didn't get it. So I find my solution. Well I will learn but I just started with WPFRoquefort
@Decoy is it good practice to make new model class for each Tabel in DB? So If I have 5 Tabels in my DB I need to have 5 model classes?Roquefort
@MiOnls please join our chat room for getting started with WPF properly and getting related technical advice WPF Chat Room. Your question isn't something i can answer in comments. But I'd say search EntityFrameworkCore to learn how to do this part properly and we can advise you more in chat once you get the hang of it.Decoy
H
-1

OK I think I see what your problem is now. It's there in your own code:

int number=0;
foreach (GroupsInList group in dataGridViewMyGroups.Items)
{
    if (fbgroupID != null && check==true)
    {
        number++;
        if (fbgroupID != groupLink)
        {
             continue;
        }
        check = false;
        continue;
    }
    //Do something and change background (code above).
   number++;
}

Your foreach loop runs as many times as there are rows in your DataGrid. But inside you increment number variable twice in some cases depending on your logic. That is, if you go in the if statement you increase it once, and then again at the end of the loop. So whenever you go in that if statement you increment your row count twice.

Which is why your counter goes to a higher value than the actual number of rows you have. You need to remove the increment inside the if statement.

Hildie answered 25/7, 2017 at 22:59 Comment(3)
do you know what continue do? I need that increment because I can't get exactly Row in which is loop in moment. I never increment number twice in one loop. Read about continue.Roquefort
I also changed .ContainerFromIndex(number); to .ContainerFromItem(group); and it work at the same way as .ContainerFromIndex(number);Roquefort
-1: I find it really weird for a 2K rep person to post double "answers" that aren't actually answers. How did you rake up the rep without learning the basic rules of Q&A on SO?!Decoy
R
-2

I resolved this problem. So the problem is because I fill DataGrid again with Data. Instead that I don't fill it I only get ID where I stopped from last time in that Table with some ID.

Code for Button Continue:

 int postID;
 string fbGroupID;
 int listID = int.Parse(cmbSelectList.SelectedValue.ToString());

 using (OleDbConnection connection = new OleDbConnection(conn))
 {

  ................

       commName.CommandText = "SELECT TOP 1 [FaceBookGroupID],[PostID] FROM [Advertiseing] WHERE [email] = @email AND [ListForGroupID]= @listID ORDER BY [Date-Time] DESC";

  ................

       postID = list[0].PostID;
       fbGroupID = list[0].FBGroupID;        
       *listID = list[0].ListForGroupID;* //Deleted
  }


  //cmbSelectList.SelectedValue = listID; - Deleted
    cmbSavedPosts.SelectedValue = postID;
  //loadGroupsInList(); - Deleted

  // Next part of code are the same
  ................
Roquefort answered 6/8, 2017 at 14:13 Comment(5)
-1 : None of this makes any sense. You're doing all of this wrong. Learn MVVM; do this properly and this question wouldn't even be needed. Even worse to offer bounty on your question and then award yourself the answer that doesn't actually answer.Decoy
I agree with Maverik, and also read this: link before posting a question next time. It will help you getting the information you need while also helping other people with similar problems. That's what Stack Overflow is all about ;)Euphemia
@Decoy I waiting too long for answer, and I didn't get it. So I find my solution. Well I will learn but I just started with WPFRoquefort
@Decoy is it good practice to make new model class for each Tabel in DB? So If I have 5 Tabels in my DB I need to have 5 model classes?Roquefort
@MiOnls please join our chat room for getting started with WPF properly and getting related technical advice WPF Chat Room. Your question isn't something i can answer in comments. But I'd say search EntityFrameworkCore to learn how to do this part properly and we can advise you more in chat once you get the hang of it.Decoy

© 2022 - 2024 — McMap. All rights reserved.