Steve15f Ответов: 1

C# WPF refresh ecran


Привет

У меня проблема с моим программным обеспечением

Мне нужно обновить свой экран с моими данными в фоновом режиме и отобразить его, когда он закончит.

У меня есть наблюдаемая коллекция :

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


Я установил datacontext в public MainWindow :
DataContext = this;


В моей пустоте, в моем цикле for я заполняю список своим классом
for()
{
Application.Current.Dispatcher.Invoke(new Action(() => _lstOperations.Add(clOp)));
}


С помощью этого метода я вижу, как экран изменяет эти данные

если я установлю свой datacontext в MainWindow :

DataContext = this;


Когда я обновляю свои данные, я вижу, что экран заполняется, а полоса прокрутки становится меньше

Если я задам datacontext значение null и это в моей функции :

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));


мои данные исчезают, экран становится черным, и появляются мои данные.

Мне нужно избегать этих двух видов поведения.

Мне нужно работать с временной ObservableCollection, чтобы замаскировать это обновление

Как действовать дальше ?

Что я уже пробовал:

В моей старой версии :

Моя привязка-это {Binding} в 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"/>


В моем коде 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;
            }
        }
    }
 
}


В моей новой версии (https://www.codeproject.com/Questions/1206951/Csharp-WPF-use-binding-with-sum?pgnumcmt2_1207134=2#cmt2_1207134) я использовал NotifyPropertyChanged с datacontext this.

Метод с listtemp не работает

1 Ответов

Рейтинг:
7

Pete O'Hanlon

Вы обнуляете DataContext, затем добавляете данные, а затем снова добавляете DataContext. Фактическая магия WPF происходит с повышением INotifyCollectionChanged.CollectionChanged, который вы удалили возможность получения WPF. На вашем месте я бы использовал вариацию чего-то вроде этот[^В принципе, отбросьте свои манипуляции с самим DataContext и сделайте это:

_lstOperations.AddRange(clOp);
Это вызовет одно уведомление о сбросе в конце, которое обновит ваш пользовательский интерфейс обновленной информацией.


Steve15f

Привет
Спасибо за ваш ответ
Я пока нет *.AddRange.
У меня есть только _lstOperations.Добавь

Потому что это не список, а наблюдаемая коллекция

Спасибо

Pete O'Hanlon

Прочтите весь ответ и перейдите по ссылке в нем. Когда вы получаете ответ, не стоит игнорировать ни одну его часть.

Steve15f

Извините но я не вижу никакой связи

Я пытался использовать .AddRange но это невозможно для observablecollection

Я вижу

Pete O'Hanlon

Ссылка, которая ясно видна там, ведет вас к этому. https://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/

Steve15f

Спасибо

Если я понимаю, я добавляю код

общественные RangeObservableCollection класс и л;т> : коллекция ObservableCollection&ЛТ;п&ГТ;
{
private bool _suppressNotification = false;

охраняемых переопределить недействительными OnCollectionChanged(NotifyCollectionChangedEventArgs е)
{
если (! _suppressNotification)
база.OnCollectionChanged(e);
}

public void AddRange(IEnumerable<t & gt; list)
{
if (list = = null)
throw new ArgumentNullException ("список");

_suppressNotification = истина;

foreach (t элемент в списке)
{
Добавить элемент);
}
_suppressNotification = ложь;
OnCollectionChanged (new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Сброс));
}
}

В мой файл MainWindow.язык XAML.в CS ?

Но я не понимаю, как я называю AddRange, извините :(

Это моя первая неделя в WPF

Pete O'Hanlon

Замените свою ObservableCollection на эту RangeObservableCollection, а затем вы можете вызвать AddRange. Это простое наследование.

Steve15f

Хорошо, спасибо, это здорово, это работа.

Но теперь у меня есть проблема с этой переменной :

частная строка _strTotaux;
публичная строка strTotaux
{
get { return _strTotaux; }
set { _strTotaux = значение; }
}



это не вид на моем экране, но до модификации все в порядке

Я не понимаю почему

У меня нет никакой ошибки Привязок

Мне нужно использовать NotifyChangedProperty, когда я заполняю свою переменную ?

strTotaux = "Nb OPs :" + dblTotalOp.ToString () + "QTE totale :" + dblTotalQte.Метод toString() + "мероприятий pces должны: Темпс итого :" + dblTotalTemps + " ч";

Pete O'Hanlon

Я бы посоветовал вам прочитать одну из многих статей, описывающих, как использовать INotifyPropertyChanged в WPF. Есть много доступных хороших статей, которые освещают это. Они покажут вам, что вам нужно сделать, чтобы вызвать вызов INPC (в качестве подсказки вы должны установить свойство, а не переменную, и вы должны вызвать событие PropertyChanged там - если вы установите переменную, вам нужно будет вызвать PropertyChanged с именем свойства впоследствии).

Graeme_Grant

Стив, в последнем вопросе я показал вам, как использовать INotifyPropertyChanged, и объяснил, зачем он нужен. Как уже упоминал Пит, без него система привязки не будет знать об обновлениях, которые вы делаете.