I am new to linq, wpf and c #. I managed to explore my path to the functional component. I successfully attacked the data binding, but I try my best to work. I am reading a static external XML file (i.e. Database) and want to display it to users using datagrid wpf. An extra bit of information is that I use the user-managed wpf combobox to filter the amount of data from the database in the grid. I would like to use linq to accomplish this task, but I cannot get it to work correctly.
C # file:
namespace ReadPipeXMLDB
{
open partial ReadDB class: window, INotifyPropertyChanged {private XDocument xmlDoc = null;
const string ALL = "All";
public ReadDB()
{
InitializeComponent();
xmlDoc = XDocument.Load("DataBase.xml");
this.DataContext = this;
}
private ObservableCollection<CPipeData> _col;
public ObservableCollection<CPipeData> Col
{
get { return _col; }
set
{
if (_col == value)
return;
_col = value;
OnPropertyChanged(() => Col);
}
}
private ObservableCollection<CMfgData> _mfgCollection;
public ObservableCollection<CMfgData> MfgCollection
{
get { return _mfgCollection; }
set
{
if (_mfgCollection == value)
return;
_mfgCollection = value;
OnPropertyChanged(() => MfgCollection);
}
}
private ObservableCollection<string> _mfgNames;
public ObservableCollection<string> MfgNames
{
get { return this._mfgNames; }
set
{
if (this._mfgNames == value)
return;
this._mfgNames = value;
OnPropertyChanged(() => MfgNames);
}
}
#region Notify Event Declaration and Definition
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged<T>(Expression<Func<T>> property)
{
PropertyChangedEventHandler eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
var memberExpression = property.Body as MemberExpression;
eventHandler(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
}
}
#endregion
public class CMfgData : ReadDB
{
private string _mfgName;
#region CMfgData Property Definitions
public string MfgName
{
get { return _mfgName; }
set
{
if (_mfgName == value)
return;
_mfgName = value;
OnPropertyChanged(() => MfgName);
}
}
#endregion
}
public class CPipeData : ReadDB
{
private string _nominal;
private string _sched;
private string _id;
private string _od;
private string _wt;
public CPipeData()
{
_nominal = "";
_sched = "";
_id = "";
_od = "";
_wt = "";
}
public CPipeData(string nominal, string sched, string id, string od, string wt)
{
_nominal = nominal;
_sched = sched;
_id = id;
_od = od;
_wt = wt;
}
#region CPipeData Property Definitions
public string Nominal
{
get { return _nominal; }
set
{
if (_nominal == value)
return;
_nominal = value;
OnPropertyChanged(() => Nominal);
}
}
public string Sched
{
get { return _sched; }
set
{
if (_sched == value)
return;
_sched = value;
OnPropertyChanged(() => Sched);
}
}
public string ID
{
get { return _id; }
set
{
if (_id == value)
return;
_id = value;
OnPropertyChanged(() => ID);
}
}
public string OD
{
get { return _od; }
set
{
if (_od == value)
return;
_od = value;
OnPropertyChanged(() => OD);
}
}
public string WT
{
get { return _wt; }
set
{
if (_wt == value)
return;
_wt = value;
OnPropertyChanged(() => WT);
}
}
#endregion
}
private void mfgrComboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (mfgrComboBox1.SelectedValue is string)
{
PopulateGrid(mfgrComboBox1.SelectedValue as string);
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
private void mfgrComboBox1_Loaded(object sender, RoutedEventArgs e)
{
if (xmlDoc != null)
{
ObservableCollection<string> tempCollection = new ObservableCollection<string>(
from n in xmlDoc.Root.Elements("Mfg").Attributes("name")
select n.Value);
tempCollection.Insert(0, ALL);
MfgNames = tempCollection;
PopulateGrid(ALL);
}
}
private void PopulateGrid(string comboValue)
{
if (mfgrComboBox1.Items.IndexOf(comboValue) > -1)
{
Col = new ObservableCollection<CPipeData>(
from mfg in xmlDoc.Root.Elements("Mfg")
where mfg.Attribute("name").Value == comboValue
from pipe in mfg.Elements("pipe")
select new CPipeData
{
Nominal = pipe.Element("Nominal").Value,
Sched = pipe.Element("Schedule").Value,
ID = pipe.Element("ID").Value,
OD = pipe.Element("OD").Value,
WT = pipe.Element("Wall_Thickness").Value
});
}
}
}
}
Xaml:
<Window x:Class="ReadPipeXMLDB.ReadDB"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Standard Pipe Sizes" Height="849" Width="949" Loaded="Window_Loaded">
<Grid>
<ComboBox Name="mfgrComboBox1"
ItemsSource="{Binding Path=MfgNames}"
SelectedIndex="0"
Height="23" Width="286"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="20,20,0,0" SelectionChanged="mfgrComboBox1_SelectionChanged" Loaded="mfgrComboBox1_Loaded" />
<ComboBox Height="23" HorizontalAlignment="Left" Margin="320,20,0,0" Name="dimensionsComboBox2" VerticalAlignment="Top" Width="87" />
<DataGrid Name="dataGrid1" IsReadOnly="True" AutoGenerateColumns="False" Margin="20,60,20,20" ItemsSource="{Binding Col}">
<DataGrid.Columns>
<DataGridTextColumn Header="Nominal" Binding="{Binding Path=Nominal}"/>
<DataGridTextColumn Header="Schedule" Binding="{Binding Path=Sched}"/>
<DataGridTextColumn Header="ID" Binding="{Binding Path=ID}"/>
<DataGridTextColumn Header="OD" Binding="{Binding Path=OD}"/>
<DataGridTextColumn Header="Wall Thickness" Binding="{Binding Path=WT}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
XML:
<DBRoot>
<Mfg name="A Manufac">
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
</Mfg>
<Mfg name="B Manufac">
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
<pipe>
<Nominal>testdata</Nominal>
<Schedule>testdata</Schedule>
<OD>testdata</OD>
<Wall_Thickness>testdata</Wall_Thickness>
<ID>testdata</ID>
</pipe>
</Mfg>
</DBRoot>
The call to PopulateGrid is slow because I create a new ObservableCollection every time the value with the list changes the value. I am not used to working with collections and linq, so if someone could offer me a more reliable alternative, I would appreciate it!