Bonjour, Je vous sollicite une nouvelle fois, c'est pas faute d'avoir chercher un peu partout mais je ne trouve pas de solution a mon problème.
Dans mon application l'utilisateur peut ajouter des usercontrol via un bouton (rien d'extraordinaire).
j'utilise une observable collection pour remplir une datagrid , mes usercontrol sont aussi bindé à cette observable collection .
Dans mon usercontrol j'utilise l'observable collection ainsi:
[Serializable]
public partial class BlockDirect : UserControl, ISerializable, INotifyPropertyChanged
{
MainWindow mainWindow = (MainWindow)Application.Current.MainWindow;
public BlockDirect()
{
InitializeComponent();
WireBox.Foreground = Brushes.Black;
BlockBox.Foreground = Brushes.Black;
TotalMulti.Foreground = Brushes.Black;
MainWindow.ListFixture.CollectionChanged += ListFixture_CollectionChanged;
DataContext = this;
}
public void GenerePropertyChanged(params string[] Props)
{
foreach (string p in Props)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p));
}
public void ListFixture_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
foreach (Fixture item in e.NewItems)
item.PropertyChanged += Fixture_PropertyChanged;
if (e.OldItems != null)
foreach (Fixture item in e.OldItems)
item.PropertyChanged -= Fixture_PropertyChanged;
}
public void Fixture_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Fixture test = sender as Fixture;
switch (e.PropertyName)
{
case "CircuitNumber" :
if (test.CircuitNumber == 1)
{
GenerePropertyChanged("Filtres1");
GenerePropertyChanged("SommeCircuit1");
}
if (test.CircuitNumber == 2)
{
GenerePropertyChanged("Filtres2");
GenerePropertyChanged("SommeCircuit2");
}
if (test.CircuitNumber == 3)
{
GenerePropertyChanged("Filtres3");
GenerePropertyChanged("SommeCircuit3");
}
}
break;
case "CircuitName":
if (test.CircuitNumber == 1)
{
GenerePropertyChanged("Filtres1");
GenerePropertyChanged("SommeCircuit1");
}
if (test.CircuitNumber == 2)
{
GenerePropertyChanged("Filtres2");
GenerePropertyChanged("SommeCircuit2");
}
if (test.CircuitNumber==3)
{
GenerePropertyChanged("Filtres3");
GenerePropertyChanged("SommeCircuit3");
}
}
break;
}
}
Quand je pose des point d’arrêt sur Fixture_PropertyChanged, je me rends compte que rien ne se déclenche.....
J'ai essayé plein de truc et a un moment donné j'ai decidé de charger 2 usercontrols au demarrage de mon appli ainsi:
Et là tout fonctionnent a merveille Fixture_PropertyChanged se déclenche bien (quand je change la valeur du circuitName ou circuitNumber dans ma datagrid) et fait son boulot, malheureusement que sur les 2 usercontrols creé au demarrage.
Si l'utilisateur en rajoute Fixture_PropertyChanged se declenche il fait son boulot mais rien ne se passe sur les usercontrol creés en runtime par l'utilsateur(aucun update)
En revanche si je charge 2 usercontroles au demarrage de l'application ainsi:
Fixture_PropertyChanged ne se declenche pas.....
Je précise également que les usercontrols créé par l'utilisateur se remplissent bien avec les bonnes données....
C'est a dire que quand je change la sélection de ma combox qui est dans le usercontrol je récupère bien les bonnes valeurs dans toute mes textboxs.
Je ne comprends pas.
Merci d'avance pour votre aide .
Bonne journée à bientot.
public class ExcelDataService
{
MainWindow mainWindow = (MainWindow)Application.Current.MainWindow;
OleDbConnection Conn;
OleDbCommand Cmd;
public ExcelDataService()
{
string ExcelFilePath = mainWindow.WygFileDirectory.Text;
string excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 12.0;Persist Security Info=True";
Conn = new OleDbConnection(excelConnectionString);
}
/// <summary>
/// Method to Get All the Records from Excel
/// </summary>
/// <returns></returns>
public async Task<ObservableCollection<Fixture>> ReadRecordFromEXCELAsync()
{
ObservableCollection<Fixture> ListFixture = new ObservableCollection<Fixture>();
char[] MyChar = { 'W', ' ' };
await Conn.OpenAsync();
Cmd = new OleDbCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "Select * from [" + mainWindow.MySheetName.Text + "$]";
var Reader = await Cmd.ExecuteReaderAsync();
if (Reader.HasRows == true)
{
while (Reader.Read())
{
ListFixture.Add(new Fixture()
{
Spot =ConvertionHelper.Converter.ConvertToInt(Reader["Spot"].ToString()),
CircuitName = Reader["Circuit Name"].ToString(),
CircuitNumber = ConvertionHelper.Converter.ConvertToInt(Reader["Circuit Number"].ToString()),
Type = Reader["Type"].ToString(),
Manufacturer = Reader["Manufacturer"].ToString(),
Wattage = ConvertionHelper.Converter.ConvertToInt(Reader["Wattage"].ToString().TrimEnd(MyChar)),
Weight = ConvertionHelper.Converter.ConvertToDecimal(Reader["Weight"].ToString().Replace(".", ",")),
Mode = Reader["Mode"].ToString(),
});
}
//MainWindow.ListFixture = new ObservableCollection<Fixture>(MainWindow.ListFixture.OrderBy(i => i.Spot));
}
Reader.Close();
Conn.Close();
return ListFixture;
}
}
Dans un usercontrol juste un ensemble de control avec des boutons/flowdoc/ControlTab:
le loadBlock 1 et 2 sont identiques juste le blockdirect.Circuit1Cbx.SelectedIndex = 1
dans le loadblock2 (c’était juste pour essayer de charger 2 blockdirect avec des données différentes.
public void LoadBlock(FlowDocument _Fd, int num, string Directname)
{
BlockDirect blockdirect = new BlockDirect();
blockdirect.Circuit1Cbx.SelectedIndex = 0;
blockdirect.Margin = new Thickness(10);
MainWindow.ListBlock.Add(blockdirect);
BlockUIContainer blockUIContainer = new BlockUIContainer();
blockdirect.Direct.Name = Directname;
blockUIContainer.Name = "blockuicontainer" + num;
blockUIContainer.Child = blockdirect;
_Fd.Blocks.Add(blockUIContainer);
//ObservableCollection<Fixture> listprovisoire = new ObservableCollection<Fixture>();
//listprovisoire.Add(MainWindow.ListFixture);
//MainWindow.ListFixture.Clear(); ///!!!!!!Avec ces lignes decommentées sa fonctionne......Une rustine!!!!!
//MainWindow.ListFixture.Add(listprovisoire);
}
le bouton d'ajout d'un blockdirect:
private void AdddirectBtn_Click(object sender, RoutedEventArgs e)
{
switch (BlockTabControl.SelectedIndex)
{
case 0:
LoadBlock(Zone01FlowDoc, 1, "DirectFd01");
break;
case 1:
LoadBlock(Zone02FlowDoc, 2, "DirectFd02");
break;
case 2:
LoadBlock(Zone03FlowDoc, 3, "DirectFd03");
break;
case 3:
LoadBlock(Zone04FlowDoc, 4, "DirectFd04");
break;
case 4:
LoadBlock(Zone05FlowDoc, 5, "DirectFd05");
break;
case 5:
LoadBlock(Zone06FlowDoc, 6, "DirectFd06");
break;
}
}
Ce matin après mon premier post j'ai rajouter les lignes commentées à la fin de Loadblock et ça fonctionne....
Mais bon c'est pas une solution....
Je me demande si la coquille vient pas du fait que
l'observable collection ListFixture est statique (je voulais avoir accès à elle de partout.....).
public MainWindow()
{
InitializeComponent();
ListFixture = new ObservableCollection<Fixture>();
DataContext = this;
}
public static ObservableCollection<Fixture> ListFixture { get; set; }
Voila Voila.
encore merci pour le temps passé à me lire.
A très bientôt.
en fait nous sommes très peu à répondre régulièrement et depuis de longs mois, je suis le seul en WPF.
Et pourtant, je suis encore loin de maitriser le XAML.
le loadBlock 1 et 2 sont identiques juste le blockdirect.Circuit1Cbx.SelectedIndex = 1
2 codes quasiment identiques, c'est une erreur. S'il y a un bug, il faut que tu le corriges 2 fois. Si le fonctionnement change, il faut que tu modifies 2 fois.
Un bon code est le plus factorisé possible => tu écris un code unique qui gère les 2 différences grâce, par exemple à un paramètre.
Il va me falloir un peu de temps pour analyser tout ça
Mon bon whismeril,
Merci pour tes réponses j'ai essayé tes solutions malheureusement ça ne change rien a mon problème ..
Je pense que mon application n' est pas vraiment codé dans les régles de l'art, dans le sens ou je n'ai pas encore assimilé toutes les subtilités lié à la programmation...
c'est pas faute de lire des bouquins , et de trainer sur différent forum....
Je vais dés demain me renseigner plus amplement sur la propriété Parent.
Pour le loadblock2 c’était juste un copier coller vite fait pour voir si quand je chargeais 2 usercontrols avec des données différentes ces 2 derniers prenaient en compte le Fixture_PropertyChanged.(ce qu'ils font).
Encore une fois merci à toi d'avoir pris sur ton temps personnel pour me lire et me répondre.
Maintenant j'ai une question un peu plus personnel .
Voila mon travail est au point mort avec le covid et c'est pas prés de reprendre....
J'ai 2000€ sur qui traine sur mon compte Cpf (compte professionnel formation).
Avec ça je vais pas aller bien loin mais, mais j'ai bien envie de les éclater....
Et me payer 1 semaine de formation Wpf/MvvM (m2iFormation a Rennes)
J'ai peur de pas avoir le niveau ....
Et avec pole emploi, mon age, j'aurais jamais une formation de plusieurs mois pour reprendre tout depuis le début...
Qu'est ce que t'en pense je l'a fait ou pas?
Je ne suis pas en mesure de répondre à ton questionnement sur cette formation tout de suite.
Et de prime abord ça s’éloigne de la question initiale et donc mériterait un sujet dédié.
Cela dit le pattern Mvvm (que j’ai personnellement assez de mal à bien appliquer [un seul projet avec un vrai codeur pour le moment]) est loin de ce que tu codes à ce jour.
Une étape intermédiaire pourrait être le MVC et le MVC pourrait aussi solutionner ton problème.
public void Fixture_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
int chiffre;
Fixture test = sender as Fixture;
switch (e.PropertyName)
{
case "CircuitNumber" : // pour avoir int chiffre
chiffre = test.CircuitNumber;
break;
case "CircuitName": // pour avoir int chiffre
chiffre = test.CircuitName;
break;
}
if (chiffre > 0 & chiffre < 4) // int chiffre va de 1 jusqu'à 3 dans les 2 choix
{
GenerePropertyChanged("Filtres" + chiffre.ToString());
GenerePropertyChanged("SommeCircuit" + chiffre.ToString());
}
}
Pour ton problème, tu pourrais peut-être utiliser une BindingList, l'événement ListChanged s'active aussi bien quand la collection est modifiée (ajout d'item, suppression , etc) que lorsqu'un item est modifié
27 juil. 2020 à 19:55
(juste répondu a ma question).
Salut bonne soirée.
27 juil. 2020 à 19:59