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 не работает