组合框与 ObservableCollection 绑定不更新
Combobox bind with ObservableCollection not updating
我试图在删除一个项目时更新一个组合框,但我无法让它工作。
我在 XML 中填充 ObservableCollection 表单,然后将其绑定到组合框,这部分工作正常。
当我单击删除按钮时,我正在从 xml 中删除,但我不知道如何触发从可观察集合中删除。
这是我目前的尝试:
ChargementScenario.Xaml
<ComboBox x:Name="cbScenario" ItemsSource="{Binding Scenarios, Mode=TwoWay}" DisplayMemberPath="name" Foreground="Black"
HorizontalAlignment="Center" VerticalAlignment="Center" Width="250" Height="40" FontFamily="/GAF-WPF;component/Resources/Font/#Barlow"
Grid.Row="0" Grid.Column="1" SelectionChanged="CbScenario_SelectionChanged">
</ComboBox>
ChargementScenario.xaml.cs
public partial class pageChargementScenario : Page
{
ObservableCollection<Scenario> listScenario = new ObservableCollection<Scenario>();
public pageChargementScenario()
{
InitializeComponent();
Loaded += pageChargementScenario_Loaded;
}
private void pageChargementScenario_Loaded(object sender, RoutedEventArgs e)
{
//VERIFICATION DE LA PRESENCE DE SCENARIO
ScenarioVM scenarioVM = new ScenarioVM();
scenarioVM.Scenarios = Scenario.loadListScenario();
if (scenarioVM.Scenarios.Count != 0)
{
DataContext = scenarioVM;
}
else
{
cbScenario.IsEnabled = false;
btnLoadScenario.Visibility = Visibility.Hidden;
btnDeleteScenario.Visibility = Visibility.Hidden;
}
}
private void CbScenario_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var scenario = (Scenario)e.AddedItems[0];
txtBoxInfoComplementaire.Text = scenario.infoComplementaire;
}
private void BtnDeleteScenario_Click(object sender, RoutedEventArgs e)
{
DialogResult result = System.Windows.Forms.MessageBox.Show($"Voulez-vous effacer le scenario {cbScenario.Text}", "SUPPRESSION SCENARIO", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
Scenario.deleteScenario(cbScenario.Text);
}
}
}
Scenario.cs
public class Scenario
{
public string name { get; set; }
public string codeClient { get; set; }
public string codeAppli { get; set; }
public string infoComplementaire { get; set; }
public string modeTelecom { get; set; }
public string extension { get; set; }
public string destination { get; set; }
public string idf { get; set; }
public string modeEnvoieFtp { get; set; }
public string typeErreur { get; set; }
public string partenaire { get; set; }
public int nombreFichier { get; set; }
public int intervalleFichier { get; set; }
public int nombreErreur { get; set; }
public Scenario()
{
}
public Scenario(string Name, string CodeClient, string CodeAppli, string InfoComplementaire, string ModeTelecom, string Idf, string Partenaire, string Extension, string Destination,
int NombreFicher, string TypeErreur, int NombreErreur, int IntervalleFichier, string ModeEnvoieFtp)
{
name = Name;
codeClient = CodeClient;
codeAppli = CodeAppli;
infoComplementaire = InfoComplementaire;
modeTelecom = ModeTelecom;
extension = Extension;
destination = Destination;
idf = Idf;
modeEnvoieFtp = ModeEnvoieFtp;
typeErreur = TypeErreur;
partenaire = Partenaire;
nombreFichier = NombreFicher;
intervalleFichier = IntervalleFichier;
nombreErreur = NombreErreur;
}
//CHARGEMENT DE LA LISTE DES SCENARIOS
public static ObservableCollection<Scenario> loadListScenario()
{
XDocument xmlScenario = new XDocument();
if (File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
//CHARGEMENT DES SCENARIOS
IEnumerable<Scenario> listeScenario = from scenario in xmlScenario.Descendants("scenario")
select new Scenario()
{
name = (string)scenario.Attribute("nom"),
codeClient = (string)scenario.Element("codeClient"),
codeAppli = (string)scenario.Element("codeApplication"),
infoComplementaire = (string)scenario.Element("informationComplementaire"),
modeTelecom = (string)scenario.Element("modeTelecom"),
extension = (string)scenario.Element("extension"),
destination = (string)scenario.Element("destination"),
idf = (string)scenario.Element("idf"),
partenaire = (string)scenario.Element("partenaire"),
nombreFichier = (int)scenario.Element("nombreFichier"),
typeErreur = (string)scenario.Element("typeErreur"),
nombreErreur = (int)scenario.Element("nombreErreur"),
intervalleFichier = (int)scenario.Element("intervalleFichier"),
modeEnvoieFtp = (string)scenario.Element("modeEnvoieFtp")
};
ObservableCollection<Scenario> collectionScenario = new ObservableCollection<Scenario>(listeScenario);
return collectionScenario;
}
else
{
return null;
}
}
public static bool checkDoublon(string scenarioName)
{
bool exist = false;
XDocument xmlScenario = new XDocument();
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
if (File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
exist = xmlScenario.Elements("listScenario").Elements("scenario")
.Any(x => x.Attribute("nom").Value == scenarioName);
}
return exist;
}
public static void saveScenario(Scenario scenario)
{
XDocument xmlScenario = new XDocument();
//CREATION DU XML SI CELUI CI N'EXISTE PAS
if (!File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
xmlScenario = new XDocument(new XElement("listScenario"));
xmlScenario.Save(ConfigurationManager.AppSettings["xmlScenario"]);
}
//CHECK SI LE SCENARIO EXISTE DEJA
bool scenarioExist = checkDoublon(scenario.name);
if (scenarioExist)
{
MessageBox.Show("UN SCENARIO DU MEME NOM EXISTE DEJA", "ERREUR NOM SCENARIO");
return;
}
//AJOUT DU NOUVEAU SCENARIO
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
XElement newScenario = new XElement("scenario", new XAttribute("nom", scenario.name),
new XElement("codeClient", scenario.codeClient),
new XElement("codeApplication", scenario.codeAppli),
new XElement("informationComplementaire", scenario.infoComplementaire),
new XElement("modeTelecom", scenario.modeTelecom),
new XElement("idf", scenario.idf),
new XElement("partenaire", scenario.partenaire),
new XElement("extension", scenario.extension),
new XElement("destination", scenario.destination),
new XElement("nombreFichier", scenario.nombreFichier),
new XElement("typeErreur", scenario.typeErreur),
new XElement("nombreErreur", scenario.nombreErreur),
new XElement("intervalleFichier", scenario.intervalleFichier),
new XElement("modeEnvoieFtp", scenario.modeEnvoieFtp)
);
xmlScenario.Root.AddFirst(newScenario);
xmlScenario.Save(ConfigurationManager.AppSettings["xmlScenario"]);
}
public static void deleteScenario(string scenarioName)
{
XDocument xmlScenario = new XDocument();
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
if (File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
var elementToRemove = xmlScenario.Elements("listScenario").Elements("scenario")
.Where(x => x.Attribute("nom").Value == scenarioName);
elementToRemove.Remove();
xmlScenario.Save(ConfigurationManager.AppSettings["xmlScenario"]);
}
}
}
ScenarioVM.cs
public class ScenarioVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private ObservableCollection<Scenario> _Scenarios { get; set; }
public ObservableCollection<Scenario> Scenarios
{
get { return _Scenarios; }
set {
_Scenarios = value;
OnPropertyChanged("Scenario");
}
}
}
我正在尝试使用 MVVC,但我对此很陌生,所以...我不知道我错过了什么...
提前致谢:)
为了从源集合中删除所选元素,您需要访问视图模型,方法是将 DataContext
属性 强制转换为视图模型类型,或者保留一个引用作为 class 成员(例如私有字段 private ScenarioVM scenarioVM;
)
if (result == DialogResult.Yes)
{
var selectedScenario = cbScenario.SelectedItem as Scenario;
if (selectedScenario != null)
{
var scenarioVM = (ScenarioVM)DataContext;
scenarioVM.Scenarios.Remove(selectedScenario);
Scenario.deleteScenario(selectedScenario.name);
}
}
请注意,您的方案 class 应遵守广泛接受的命名约定,属性 名称使用 PascalCase,局部变量和方法参数名称使用 camelCase:
public class Scenario
{
public string Name { get; set; }
...
public Scenario(string name, ...)
{
Name = name;
...
}
}
我试图在删除一个项目时更新一个组合框,但我无法让它工作。
我在 XML 中填充 ObservableCollection 表单,然后将其绑定到组合框,这部分工作正常。
当我单击删除按钮时,我正在从 xml 中删除,但我不知道如何触发从可观察集合中删除。
这是我目前的尝试:
ChargementScenario.Xaml
<ComboBox x:Name="cbScenario" ItemsSource="{Binding Scenarios, Mode=TwoWay}" DisplayMemberPath="name" Foreground="Black"
HorizontalAlignment="Center" VerticalAlignment="Center" Width="250" Height="40" FontFamily="/GAF-WPF;component/Resources/Font/#Barlow"
Grid.Row="0" Grid.Column="1" SelectionChanged="CbScenario_SelectionChanged">
</ComboBox>
ChargementScenario.xaml.cs
public partial class pageChargementScenario : Page
{
ObservableCollection<Scenario> listScenario = new ObservableCollection<Scenario>();
public pageChargementScenario()
{
InitializeComponent();
Loaded += pageChargementScenario_Loaded;
}
private void pageChargementScenario_Loaded(object sender, RoutedEventArgs e)
{
//VERIFICATION DE LA PRESENCE DE SCENARIO
ScenarioVM scenarioVM = new ScenarioVM();
scenarioVM.Scenarios = Scenario.loadListScenario();
if (scenarioVM.Scenarios.Count != 0)
{
DataContext = scenarioVM;
}
else
{
cbScenario.IsEnabled = false;
btnLoadScenario.Visibility = Visibility.Hidden;
btnDeleteScenario.Visibility = Visibility.Hidden;
}
}
private void CbScenario_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var scenario = (Scenario)e.AddedItems[0];
txtBoxInfoComplementaire.Text = scenario.infoComplementaire;
}
private void BtnDeleteScenario_Click(object sender, RoutedEventArgs e)
{
DialogResult result = System.Windows.Forms.MessageBox.Show($"Voulez-vous effacer le scenario {cbScenario.Text}", "SUPPRESSION SCENARIO", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
Scenario.deleteScenario(cbScenario.Text);
}
}
}
Scenario.cs
public class Scenario
{
public string name { get; set; }
public string codeClient { get; set; }
public string codeAppli { get; set; }
public string infoComplementaire { get; set; }
public string modeTelecom { get; set; }
public string extension { get; set; }
public string destination { get; set; }
public string idf { get; set; }
public string modeEnvoieFtp { get; set; }
public string typeErreur { get; set; }
public string partenaire { get; set; }
public int nombreFichier { get; set; }
public int intervalleFichier { get; set; }
public int nombreErreur { get; set; }
public Scenario()
{
}
public Scenario(string Name, string CodeClient, string CodeAppli, string InfoComplementaire, string ModeTelecom, string Idf, string Partenaire, string Extension, string Destination,
int NombreFicher, string TypeErreur, int NombreErreur, int IntervalleFichier, string ModeEnvoieFtp)
{
name = Name;
codeClient = CodeClient;
codeAppli = CodeAppli;
infoComplementaire = InfoComplementaire;
modeTelecom = ModeTelecom;
extension = Extension;
destination = Destination;
idf = Idf;
modeEnvoieFtp = ModeEnvoieFtp;
typeErreur = TypeErreur;
partenaire = Partenaire;
nombreFichier = NombreFicher;
intervalleFichier = IntervalleFichier;
nombreErreur = NombreErreur;
}
//CHARGEMENT DE LA LISTE DES SCENARIOS
public static ObservableCollection<Scenario> loadListScenario()
{
XDocument xmlScenario = new XDocument();
if (File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
//CHARGEMENT DES SCENARIOS
IEnumerable<Scenario> listeScenario = from scenario in xmlScenario.Descendants("scenario")
select new Scenario()
{
name = (string)scenario.Attribute("nom"),
codeClient = (string)scenario.Element("codeClient"),
codeAppli = (string)scenario.Element("codeApplication"),
infoComplementaire = (string)scenario.Element("informationComplementaire"),
modeTelecom = (string)scenario.Element("modeTelecom"),
extension = (string)scenario.Element("extension"),
destination = (string)scenario.Element("destination"),
idf = (string)scenario.Element("idf"),
partenaire = (string)scenario.Element("partenaire"),
nombreFichier = (int)scenario.Element("nombreFichier"),
typeErreur = (string)scenario.Element("typeErreur"),
nombreErreur = (int)scenario.Element("nombreErreur"),
intervalleFichier = (int)scenario.Element("intervalleFichier"),
modeEnvoieFtp = (string)scenario.Element("modeEnvoieFtp")
};
ObservableCollection<Scenario> collectionScenario = new ObservableCollection<Scenario>(listeScenario);
return collectionScenario;
}
else
{
return null;
}
}
public static bool checkDoublon(string scenarioName)
{
bool exist = false;
XDocument xmlScenario = new XDocument();
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
if (File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
exist = xmlScenario.Elements("listScenario").Elements("scenario")
.Any(x => x.Attribute("nom").Value == scenarioName);
}
return exist;
}
public static void saveScenario(Scenario scenario)
{
XDocument xmlScenario = new XDocument();
//CREATION DU XML SI CELUI CI N'EXISTE PAS
if (!File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
xmlScenario = new XDocument(new XElement("listScenario"));
xmlScenario.Save(ConfigurationManager.AppSettings["xmlScenario"]);
}
//CHECK SI LE SCENARIO EXISTE DEJA
bool scenarioExist = checkDoublon(scenario.name);
if (scenarioExist)
{
MessageBox.Show("UN SCENARIO DU MEME NOM EXISTE DEJA", "ERREUR NOM SCENARIO");
return;
}
//AJOUT DU NOUVEAU SCENARIO
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
XElement newScenario = new XElement("scenario", new XAttribute("nom", scenario.name),
new XElement("codeClient", scenario.codeClient),
new XElement("codeApplication", scenario.codeAppli),
new XElement("informationComplementaire", scenario.infoComplementaire),
new XElement("modeTelecom", scenario.modeTelecom),
new XElement("idf", scenario.idf),
new XElement("partenaire", scenario.partenaire),
new XElement("extension", scenario.extension),
new XElement("destination", scenario.destination),
new XElement("nombreFichier", scenario.nombreFichier),
new XElement("typeErreur", scenario.typeErreur),
new XElement("nombreErreur", scenario.nombreErreur),
new XElement("intervalleFichier", scenario.intervalleFichier),
new XElement("modeEnvoieFtp", scenario.modeEnvoieFtp)
);
xmlScenario.Root.AddFirst(newScenario);
xmlScenario.Save(ConfigurationManager.AppSettings["xmlScenario"]);
}
public static void deleteScenario(string scenarioName)
{
XDocument xmlScenario = new XDocument();
xmlScenario = XDocument.Load(ConfigurationManager.AppSettings["xmlScenario"]);
if (File.Exists(ConfigurationManager.AppSettings["xmlScenario"]))
{
var elementToRemove = xmlScenario.Elements("listScenario").Elements("scenario")
.Where(x => x.Attribute("nom").Value == scenarioName);
elementToRemove.Remove();
xmlScenario.Save(ConfigurationManager.AppSettings["xmlScenario"]);
}
}
}
ScenarioVM.cs
public class ScenarioVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private ObservableCollection<Scenario> _Scenarios { get; set; }
public ObservableCollection<Scenario> Scenarios
{
get { return _Scenarios; }
set {
_Scenarios = value;
OnPropertyChanged("Scenario");
}
}
}
我正在尝试使用 MVVC,但我对此很陌生,所以...我不知道我错过了什么...
提前致谢:)
为了从源集合中删除所选元素,您需要访问视图模型,方法是将 DataContext
属性 强制转换为视图模型类型,或者保留一个引用作为 class 成员(例如私有字段 private ScenarioVM scenarioVM;
)
if (result == DialogResult.Yes)
{
var selectedScenario = cbScenario.SelectedItem as Scenario;
if (selectedScenario != null)
{
var scenarioVM = (ScenarioVM)DataContext;
scenarioVM.Scenarios.Remove(selectedScenario);
Scenario.deleteScenario(selectedScenario.name);
}
}
请注意,您的方案 class 应遵守广泛接受的命名约定,属性 名称使用 PascalCase,局部变量和方法参数名称使用 camelCase:
public class Scenario
{
public string Name { get; set; }
...
public Scenario(string name, ...)
{
Name = name;
...
}
}