#c# #xml #wpf
#c# #xml #wpf
Вопрос:
У меня есть XML-файл и привязка к сетке данных WPF. Также у меня есть метод, который обновляет XML-файл. Но после редактирования xml DataGrid не обновляется автоматически. Возможно ли обновить сетку данных?
Вот код xaml:
<Window x:Class="TestWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestWPF"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="750" Name ="Window" >
<Grid Margin="-16,-34,-8,-96">
<DataGrid x:Name="Dgr_Archive" HorizontalAlignment="Left" Height="215" Margin="25,375,0,0" VerticalAlignment="Top" Width="725"
ItemsSource="{Binding}" AutoGenerateColumns="False" GridLinesVisibility="Horizontal">
<DataGrid.DataContext>
<XmlDataProvider Source="C:Users1sourcereposTestWPFTestWPFArchive.xml" XPath="/Companies/Company" />
</DataGrid.DataContext>
<DataGrid.Columns >
<DataGridTextColumn Width="25" Header="ID" Binding="{Binding XPath=@id}">
<DataGridTextColumn Width="110" Header="Company Name" Binding="{Binding XPath=@name}"/>
<DataGridTextColumn Width="110" Header="Position" Binding="{Binding XPath=Position}"/>
<DataGridTextColumn Width="110" Header="Address" Binding="{Binding XPath=Address}"/>
<DataGridTextColumn Width="110" Header="E mail" Binding="{Binding XPath=E_mail}"/>
<DataGridTextColumn Width="119" Header="Contact person" Binding="{Binding Path=Contact_person}"/>
<DataGridTextColumn Width="116" Header="Record Timestamp" Binding="{Binding XPath=Record_Timestamp}"/>
</DataGrid>
</Grid>
</Window>
И вот код Medhod C # для добавления записи в xml
private void Add_record(XDocument doc)
{
XElement n = doc.Root.LastNode as XElement;
Int32.TryParse(n.Attribute("id").Value, out int LastElementID);
doc.Root.Add(new XElement("Company",
new XElement("Position", Tbx_Position.Text),
new XElement("Address", Tbx_Address.Text " " Tbx_PLZOrt.Text),
new XElement("E_mail", Tbx_Email.Text),
new XElement("Contact_person", Tbx_Person.Text),
new XElement("Record_Timestamp", DateTime.Now.ToString()),
new XAttribute("name", Tbx_Company_Name.Text.Replace(" ", "_")),
new XAttribute("id", (LastElementID 1))));
doc.Save(archpath);
Комментарии:
1. Вам нужно будет реализовать интерфейс INotifyPropertyChanged для строк в вашем ItemsSource
2. Если вы редактируете в сетке, вам также понадобится mode=TwoWay в ваших привязках
Ответ №1:
Я использую приведенный ниже класс для всех моих объектов (ваши элементы строк в ItemsSource).
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace eTabber.Data.Model
{
public class PropertyChangedEntity : INotifyPropertyChanged
{
public void NotifyPropertyChangedRefType<TValue>(ref TValue oldValue, TValue newValue, [CallerMemberName] string name = null)
where TValue : class
{
if (string.IsNullOrEmpty(name)) throw new InvalidOperationException("Name cannot be null!");
if (oldValue == null)
{
if (newValue != null amp;amp; !newValue.Equals(oldValue))
{
SetAndNotify(ref oldValue, newValue, name);
}
}
else
{
if (!oldValue.Equals(newValue))
{
SetAndNotify(ref oldValue, newValue, name);
}
}
}
private void SetAndNotify<TValue>(ref TValue oldValue, TValue newValue, string name) where TValue : class
{
oldValue = newValue;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public void NotifyPropertyChangedValueType<TValue>(ref TValue oldValue, TValue newValue, [CallerMemberName] string name = null)
{
if (string.IsNullOrEmpty(name)) throw new InvalidOperationException("Name cannot be null!");
if (!newValue.Equals(oldValue))
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
oldValue = newValue;
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
И можете использовать это так в своих производных классах:
public class Account : PropertyChangedEntity
{
...
DateTime _ModificationsTimestamp;
/// <summary>
/// Timestamp for modifications
/// </summary>
public DateTime ModificationsTimestamp { get => _ModificationsTimestamp; set => NotifyPropertyChangedValueType(ref _ModificationsTimestamp, value); }
private HashSet<SetList> _SetLists;
/// <summary>
/// Setlistst belonging to this account
/// </summary>
public HashSet<SetList> SetLists { get => _SetLists; set => NotifyPropertyChangedRefType(ref _SetLists, value); }
}