Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello

I have a problem with my software

I need to refresh my screen with my datas in background and display when it's finish.

I have a ObservableCollection :

private ObservableCollection<CL_Operation> _lstOperations = new ObservableCollection<CL_Operation>();
        public ObservableCollection<CL_Operation> LstOperations
        {
            get { return _lstOperations; }
            set { _lstOperations = value; }
        }


I set the datacontext in public MainWindow :
DataContext = this;


In my void, in my for loop i fill a list with my class
for()
{
Application.Current.Dispatcher.Invoke(new Action(() => _lstOperations.Add(clOp)));
}


With this method, i see the screen change this data

if i set my datacontext in MainWindow :

DataContext = this;


When i refresh my datas, I see the screen fill and the scrollbar become smaller

If i set the datacontext to null and to this in my function :

Application.Current.Dispatcher.Invoke(new Action(() => this.DataContext = null))
for()
{
Application.Current.Dispatcher.Invoke(new Action(() => _lstOperations.Add(clOp)));
}
Application.Current.Dispatcher.Invoke(new Action(() => this.DataContext = this));


my data disappear the screen turns black and my data appear.

I need to avoid these two behaviours.

I need to work with a temporary ObservableCollection to mask this update

How proceed ?

What I have tried:

In my old version :

My binding is {Binding} in XAML :

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Plutus" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="Plutus.MainWindow"
    Title="MainWindow" Height="523.725" Width="898" Background="#FF3A3939" WindowStartupLocation="CenterScreen" WindowState="Maximized">
<window.resources>
    
        <Setter Property="Width" Value="35"/>
    
 
<grid>
    <grid.columndefinitions>
        <ColumnDefinition />
    
    <grid.rowdefinitions>
        <RowDefinition Height="0.03*" />
        <RowDefinition Height="0.04*" />
        <RowDefinition Height="0.04*" />
        <RowDefinition Height="0.88*"/>
        <RowDefinition Height="0.02*" />
    
    
    
 
    
<ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Row="3" >
    <ItemsControl VerticalAlignment="Top" x:Name="lvDataBinding" HorizontalContentAlignment="Stretch" BorderThickness="0" Margin="10" Grid.Row="3" Background="{x:Null}" ItemsSource="{Binding}" Foreground="White">
        <itemscontrol.itemtemplate>
            <DataTemplate DataType="{x:Type local:CL_Operation}">
                <Border BorderBrush="White" BorderThickness="1" CornerRadius="3" Margin="0,3" Grid.ColumnSpan="0" Background="Transparent" HorizontalAlignment="Left" VerticalAlignment="Top">
                    <Grid Width="{Binding strWidth}" Height="60" Background="Transparent" Margin="0,1">
                        <grid.columndefinitions>
                                <ColumnDefinition Width="0.06*" />
                                <ColumnDefinition Width="0.09*" />
                                <ColumnDefinition Width="0.1*" />
                                <ColumnDefinition Width="0.12*" />
                                <ColumnDefinition Width="0.1*" />
                                <ColumnDefinition Width="0.1*" />
                                <ColumnDefinition Width="0.1*" />
                                <ColumnDefinition Width="0.05*" />
                                <ColumnDefinition Width="0.05*" />
                                <ColumnDefinition Width="0.05*" />
                                <ColumnDefinition Width="0.05*" />
                                <ColumnDefinition Width="0.03*" />
                            
                        <grid.rowdefinitions>
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                        
                            <UniformGrid Tag="{Binding strRueck}"  Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" MouseLeftButtonUp="Test" >
                                <uniformgrid.style>
                                    
                                        <Style.Triggers>
                                            <Trigger Property="IsMouseOver" Value="true">
                                                <Setter Property="Background" Value="White"/>
                                            </trigger>
                                            <Trigger Property="IsMouseOver" Value="false">
                                                <Setter Property="Background" Value="{Binding scbBackColor}"/>
                                            </trigger>
                                        </style.Triggers>
                                    
                                
                                <TextBlock Text="{Binding strPriorite}" FontSize="36" Foreground="Red" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold"/>
                        
                            <UniformGrid  Grid.Column="0" Grid.Row="2"  Background="{Binding scbBackColor}" MouseLeftButtonUp="Test" >
                                <TextBlock Text="{Binding strSsSect}" FontSize="14" Foreground="Black" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontWeight="Bold" />
                            
                            <UniformGrid  Grid.Column="1" Grid.Row="0" Grid.RowSpan="3">
                            <TextBlock Text="{Binding strRetardAvanceText}" FontSize="28" Foreground="{Binding scbColorRetardAvance}" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        
                        <UniformGrid  Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="2" Grid.RowSpan="2">
                            <uniformgrid.style>
                                
                                    <Style.Triggers>
                                        <Trigger Property="IsMouseOver" Value="true">
                                            <Setter Property="Background" Value="Gray"/>
                                        </trigger>
                                    </style.Triggers>
                                
                            
                                <TextBlock Tag="{Binding strRueck}" Foreground="{Binding scbColorNumOfOp}" Text="{Binding strNoOfOp}" FontSize="26" FontWeight="Bold" MouseLeftButtonUp="Test"/>
                        
                        <UniformGrid  Grid.Column="2" Grid.Row="2" Grid.ColumnSpan="3">
                            <TextBlock Text="{Binding strDescriptionOp}" FontSize="14" Foreground="White"/>
                        
                        <UniformGrid Grid.Column="4" Grid.Row="0">
                            <TextBlock Text="{Binding strNoArticle}" FontSize="14" Foreground="White"/>
                        
                        <UniformGrid  Grid.Column="4" Grid.Row="1">
                            <TextBlock Text="{Binding strDateFormatee}" FontSize="14" Foreground="White"/>
                        
                        <UniformGrid Grid.Column="5" Grid.Row="0">
                            <TextBlock Text="{Binding strPcesPoste}" FontSize="14" Foreground="White"/>
                        
                        <UniformGrid  Grid.Column="5" Grid.Row="1">
                            <TextBlock Text="{Binding strTpsPoste}" FontSize="14" Foreground="White"/>
                        
                        <UniformGrid  Grid.Column="6" Grid.Row="0">
                            <TextBlock Text="{Binding strTempsPoste}" FontSize="14" Foreground="White"/>
                        
                        <UniformGrid  Grid.Column="6" Grid.Row="1">
                            <TextBlock Text="{Binding strClient}" FontSize="14" Foreground="White"/>
                        
                        <UniformGrid  Grid.Column="5" Grid.Row="2" Grid.ColumnSpan="3">
                            <TextBlock Text="{Binding strTypeOp}" FontSize="14" Foreground="White"/>
                        
                            <UniformGrid  Grid.Column="9" Grid.Row="3">
                                <TextBlock Text="{Binding strAuart}" FontSize="12" Foreground="White" FontWeight="Bold"/>
                            
                        
                
            
        
        <itemscontrol.itemspanel>
            <itemspaneltemplate>
                <UniformGrid Columns="2"/>


In my c# code you can see, i filled a temp list, when it's ok, i send in second list to send in binding :

C#
public partial class MainWindow : Window
{
    public ObservableCollection<cl_operation> lstOperationsTemp = new ObservableCollection<cl_operation>();
 
    public List<string> lstSelectedLignesChoisi = new List<string>();
    public List<string> lstSelectedIlotsChoisi = new List<string>();
    public List<string> lstPostesTravailChoisi = new List<string>();
 

    DispatcherTimer dtTimer = new DispatcherTimer();
 
    DataTable dtOps = new DataTable();
    DataView dvOps = new DataView();
 
    Thread thrGetList;
 
    string connectionString = "Data Source=SERVER\\INSTANCE;Initial Catalog=DB;Integrated Security=True";
    string strOrderBy;
    string strResultTri;
    string strWhere;
    string strWhereLigne;
    string strWhereIlot;
    string strWherePosteTravail;
 
    int iTimer = 30;
 
    public MainWindow()
    {
        InitializeComponent();
 
        dtTimer.Tick += new EventHandler(timer_Tick);
        dtTimer.Interval = new TimeSpan(0, 0, 1);
        //dtTimer.Start();
 
        thrGetList = new Thread(GetList);
        thrGetList.Start();
    }
 
    public CL_Operation clOp { get; set; }
 
    public void GetList()
    {
        dvOps = dtOps.DefaultView;
 
        Application.Current.Dispatcher.Invoke(new Action(() => lstOperationsTemp.Clear()));
        dtOps.Clear();
 
        string strQueryDatas;
 
        SqlConnection con = new SqlConnection(connectionString);
 
        strQueryDatas = "SELECT * FROM [DB].[dbo].[VIEW] " + strWhere + " " + strOrderBy;
 
        SqlDataAdapter adOps = new SqlDataAdapter(strQueryDatas, con);
 
        adOps.Dispose();
 
        try
        {
            con.Open();
            SqlCommand sqlCmd = new SqlCommand(strQueryDatas, con);
            sqlCmd.CommandTimeout = 500;
            adOps.SelectCommand = sqlCmd;
            adOps.Fill(dtOps);
            adOps.Dispose();
            sqlCmd.Dispose();
            con.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
 
        DateTime dtNow = DateTime.Now;
 
        double dblTotalQte = 0;
        double dblTotalOp = 0;
        double dblTotalTemps=0;
 
        for (int i = 0; i < dvOps.Count; i++)
        {
            clOp = new CL_Operation();
 
            clOp.strWidth = Convert.ToString(Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenWidth) / 2);
 
            clOp.strNoOfOp = dvOps[i]["NumOF"].ToString().Trim() + " - " + dvOps[i]["NumOP"].ToString().Trim();
            clOp.strAuart = dvOps[i]["AUART"].ToString().Trim();
            clOp.strMaufnr = dvOps[i]["MAUFNR"].ToString().Trim();
            clOp.strCodeLigne = dvOps[i]["CodeLigne"].ToString().Trim();
            //clOp.strNumOp = dvOps[i]["NumOP"].ToString().Trim();
            clOp.strRueck = dvOps[i]["RUECK"].ToString().Trim();
            clOp.strDescriptionOp = dvOps[i]["DesOpe"].ToString().Trim();
            clOp.strNoArticle = dvOps[i]["NumArt"].ToString().Trim();
            clOp.strDateFormatee = dvOps[i]["DateFormatee"].ToString().Trim();
            clOp.strPcesPoste = Convert.ToString(Convert.ToDouble(String.Format("{0:0}", dvOps[i]["QtePoste"].ToString().Trim()))) + " pces";
            clOp.strTpsPoste = Convert.ToString(Convert.ToDouble(String.Format("{0:0.00}", dvOps[i]["TpsChargePoste"].ToString()))) + " Hrs";
            clOp.strClient = dvOps[i]["NomClientCourt"].ToString().Trim();
            clOp.strTypeOp = dvOps[i]["MAKTX"].ToString();
            clOp.strPriorite = dvOps[i]["PriorOF"].ToString();
            clOp.strSsSect = dvOps[i]["SsSect"].ToString();
            clOp.strDateDerBadge = Convert.ToDateTime(dvOps[i]["DatDerBadg"]);
 
            // Here i sum my quantity
            dblTotalQte += Convert.ToDouble(dvOps[i]["QtePoste"].ToString().Trim());
            dblTotalTemps += Convert.ToDouble(dvOps[i]["TpsChargePoste"].ToString().Trim());
            dblTotalOp++;
 
            // I need to display this result in my label
            clOp.strTotaux = "Nb OPs : " + dblTotalOp.ToString() + " Qte totale : " + dblTotalQte.ToString() + " Pces Temps total : " + dblTotalTemps + " Hrs";
 
            Application.Current.Dispatcher.Invoke(new Action(() => lstOperationsTemp.Add(clOp)));
 
            DateTime dtRetard = Convert.ToDateTime(clOp.strDateFormatee);
            DateTime dtTempsPoste = Convert.ToDateTime(clOp.strDateDerBadge);
            TimeSpan tRetard = dtNow.Date - dtRetard.Date;
            TimeSpan tTempsPoste = dtNow - dtTempsPoste;
 
            clOp.strRetardAvanceText = Convert.ToString(Math.Abs(Convert.ToDouble(tRetard.TotalDays))) + " jrs";
 
            clOp.scbBackColor.Freeze();
            clOp.scbColorRetardAvance.Freeze();
 
        }
 
        ObservableCollection<cl_operation> lstOperations = new ObservableCollection<cl_operation>(lstOperationsTemp);
 
        Application.Current.Dispatcher.Invoke(new Action(() => this.DataContext = lstOperations));
 
    }
 
    private void Test(object sender, MouseButtonEventArgs e)
    {
        string str = ((TextBlock)sender).Tag.ToString();
 
        MessageBox.Show(str);
 
        foreach (var item in lstOperationsTemp)
        {
            if (item.strRueck == str)
            {
                MessageBox.Show(item.strNoOfOp);
                break;
            }
        }
    }
 
}


In my new version (https://www.codeproject.com/Questions/1206951/Csharp-WPF-use-binding-with-sum?pgnumcmt2_1207134=2#cmt2_1207134) i used the NotifyPropertyChanged with datacontext this.

The method with listtemp don't work
Posted
Updated 21-Sep-17 3:49am
v3

1 solution

You're nulling out the DataContext, then adding the data and then adding the DataContext back in. The actual WPF magic happens with the raising of INotifyCollectionChanged.CollectionChanged, which you have removed the ability for WPF to receive. If I were you, I would use a variation of something like this[^]. Basically, drop your manipulation of the DataContext itself, and do this:
C#
_lstOperations.AddRange(clOp);
This will raise a single Reset notification at the end which will refresh your UI with the updated information.
 
Share this answer
 
Comments
Steve15f 21-Sep-17 10:02am    
Hello
Thank you for your reply
I don't have *.AddRange.
I have only _lstOperations.Add

Because, it's not a list, it's an ObservableCollection

Thank you
Pete O'Hanlon 21-Sep-17 10:21am    
Read the whole reply and follow the link in it. When you get an answer, it pays not to ignore any part of it.
Steve15f 21-Sep-17 10:22am    
Sorry but i don't see a link

I tried to use .AddRange but it's not possible on an observablecollection

I see
Pete O'Hanlon 21-Sep-17 10:27am    
The link, which is plain in there, takes you to this. https://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/
Steve15f 21-Sep-17 10:32am    
Thank you

If i understand, i add the code

public class RangeObservableCollection<t> : ObservableCollection<t>
{
private bool _suppressNotification = false;

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (!_suppressNotification)
base.OnCollectionChanged(e);
}

public void AddRange(IEnumerable<t> list)
{
if (list == null)
throw new ArgumentNullException("list");

_suppressNotification = true;

foreach (T item in list)
{
Add(item);
}
_suppressNotification = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}

In my MainWindow.xaml.cs ?

But i don't understand how i call AddRange, sorry :(

It's my first week in WPF

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900