WIP - Generics Implementation

This commit is contained in:
Francesco 2020-07-23 16:29:59 +02:00
parent 14346596b5
commit 08a53739ee
18 changed files with 1020 additions and 107 deletions

View File

@ -80,14 +80,22 @@
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Model\Model.cs" /> <Compile Include="Model\Model.cs" />
<Compile Include="Model\Location.cs" /> <Compile Include="Model\Location.cs" />
<Compile Include="Model\Node.cs" />
<Compile Include="Model\SeverityComboBoxItem.cs" /> <Compile Include="Model\SeverityComboBoxItem.cs" />
<Compile Include="Repository\IRepositoryBase.cs" /> <Compile Include="Repository\IRepositoryBase.cs" />
<Compile Include="Repository\LocationRepository.cs" /> <Compile Include="Repository\LocationRepository.cs" />
<Compile Include="Repository\LoggingRepository.cs" /> <Compile Include="Repository\LoggingRepository.cs" />
<Compile Include="Repository\RepositoryBase.cs" /> <Compile Include="Repository\RepositoryBase.cs" />
<Compile Include="Validators\IntRangeValidationRule.cs" /> <Compile Include="Validators\IntRangeValidationRule.cs" />
<Compile Include="ViewModel\Commands\BaseCommand.cs" />
<Compile Include="ViewModel\Commands\RelayCommand.cs" /> <Compile Include="ViewModel\Commands\RelayCommand.cs" />
<Compile Include="Validators\StringRangeValidationRule.cs" /> <Compile Include="Validators\StringRangeValidationRule.cs" />
<Compile Include="ViewModel\LocationTreeBuilder.cs" />
<Compile Include="ViewModel\LocationViewModel.cs" />
<Compile Include="ViewModel\NavigationViewModel.cs" />
<Compile Include="Views\LocationView.xaml.cs">
<DependentUpon>LocationView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LogView.xaml.cs"> <Compile Include="Views\LogView.xaml.cs">
<DependentUpon>LogView.xaml</DependentUpon> <DependentUpon>LogView.xaml</DependentUpon>
</Compile> </Compile>
@ -105,6 +113,10 @@
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Page Include="Views\LocationView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LogView.xaml"> <Page Include="Views\LogView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

36
LoggingClient/LoggingClient/MainWindow.xaml Normal file → Executable file
View File

@ -2,8 +2,40 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:LoggingClient.Views" xmlns:views="clr-namespace:LoggingClient.Views"
xmlns:local="clr-namespace:LoggingClient.ViewModel"
Title="MainWindow" Height="450" Width="800" ResizeMode="NoResize"> Title="MainWindow" Height="450" Width="800" ResizeMode="NoResize">
<Grid> <!--<Grid>
<views:LogView x:Name = "LogView"/> <views:LogView x:Name = "LogView"/>
</Grid> </Grid>-->
<Window.Resources>
<DataTemplate DataType="{x:Type local:LogViewModel}">
<views:LogView/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:LocationViewModel}">
<views:LocationView/>
</DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
<Grid x:Name="Navigation" DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Width="400" Content="Locations" Command="{Binding LocationsCommand}" Margin="394,0,-393,0"/>
<Button HorizontalAlignment="Right" Width="400" Content="Log Reader" Command="{Binding LogsCommand}" Margin="0,0,2,0"/>
</Grid>
<ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}"/>
</DockPanel>
</Window> </Window>

View File

@ -1,12 +1,26 @@
using System; namespace LoggingClient.Model
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LoggingClient.Model
{ {
class Location : Model public class Location : Model<Location>
{ {
public int ParentId { get; set; }
public int AddressId { get; set; }
public string Designation { get; set; }
public int BuildingNr { get; set; }
public int RoomNr { get; set; }
public Location()
{
// Emty Constructor
}
public Location(int id, int parentId, int addressId, string designation, int buildingNr, int roomNr)
{
this.Id = id;
this.ParentId = parentId;
this.AddressId = addressId;
this.Designation = designation;
this.BuildingNr = buildingNr;
this.RoomNr = roomNr;
}
} }
} }

View File

@ -2,9 +2,8 @@
namespace LoggingClient.Model namespace LoggingClient.Model
{ {
public class Logging : Model public class Logging : Model<Logging>
{ {
public int Id { get; set; }
public string Pod { get; set; } public string Pod { get; set; }
public string Location { get; set; } public string Location { get; set; }
public string Hostname { get; set; } public string Hostname { get; set; }

View File

@ -1,13 +1,9 @@
using System; using DuplicateCheckerLib;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DuplicateCheckerLib;
namespace LoggingClient.Model namespace LoggingClient.Model
{ {
public class Model : IEntity public abstract class Model<M> : IEntity
{ {
public int Id { get; set; }
} }
} }

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LoggingClient.Model
{
public class Node<M>
{
public M ValueObject { get; set; }
public Node<M> ParentNode { get; set; }
public List<Node<M>> ChildNodesList { get; set; }
public Node()
{
this.ChildNodesList = new List<Node<M>>();
}
public Node(M valueObject)
{
this.ValueObject = valueObject;
this.ParentNode = default;
this.ChildNodesList = new List<Node<M>>();
}
public Node(Node<M> parentNode, M valueObject)
{
this.ValueObject = valueObject;
this.ParentNode = parentNode;
this.ChildNodesList = new List<Node<M>>();
}
public void AddChildNode(Node<M> childNode)
{
this.ChildNodesList.Add(childNode);
}
public override string ToString()
{
if (ValueObject != null)
{
return ValueObject.ToString();
}
return "-1";
}
}
}

View File

@ -13,5 +13,4 @@ namespace LoggingClient.Model
public int Id { get; set; } public int Id { get; set; }
public int Severity { get; set; } public int Severity { get; set; }
} }
} }

View File

@ -1,50 +1,198 @@
using LoggingClient.Model; using LoggingClient.Model;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows;
namespace LoggingClient.Repository namespace LoggingClient.Repository
{ {
class LocationRepository : RepositoryBase<Location> class LocationRepository : RepositoryBase<Location>
{ {
public override string TableName => throw new System.NotImplementedException(); public override string TableName => "Location";
public override string ColumnsForSelect => "location_id, parent_location, address_fk, designation, building, room";
public override string ColumnsForAdd => "parent_location, address_fk, designation, building, room";
public override string PrimaryKeyFromTable => "location_id";
public override void Add(Location entity) public List<Location> Locations { get; set; }
public Location _Locations { get; set; }
public LocationRepository(string connectionString) : base(connectionString)
{ {
throw new System.NotImplementedException(); Locations = new List<Location>();
}
public override void Add(Location location)
{
try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText =
$"INSERT INTO {TableName} ({ColumnsForAdd}) " +
$"VALUES " +
$"(parentId = {location.ParentId}, address_fk = {location.AddressId} , designation = '{location.Designation}', building = {location.BuildingNr} , room = {location.RoomNr} )";
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
} }
public override long Count(string whereCondition, Dictionary<string, object> parameterValues) public override void Delete(Location location)
{ {
throw new System.NotImplementedException(); try
} {
using (var conn = new MySqlConnection(ConnectionString))
public override long Count() {
{ conn.Open();
throw new System.NotImplementedException(); using (MySqlCommand cmd = conn.CreateCommand())
} {
cmd.CommandText = $"DELETE FROM {TableName} WHERE location_id = {location.Id}";
public override void Delete(Location entity) cmd.ExecuteNonQuery();
{ }
throw new System.NotImplementedException(); }
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
} }
public override List<Location> GetAll(string whereCondition, Dictionary<string, object> parameterValues) public override List<Location> GetAll(string whereCondition, Dictionary<string, object> parameterValues)
{ {
throw new System.NotImplementedException(); var whereCon = whereCondition;
if (parameterValues.Count > 0 && whereCondition != null)
{
foreach (KeyValuePair<string, object> p in parameterValues)
{
whereCon = whereCon.Replace($"@{p.Key}", p.Value.ToString());
}
}
try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT {ColumnsForSelect} FROM {TableName} WHERE {whereCon}";
var reader = cmd.ExecuteReader();
while (reader.Read())
{
Locations.Add(new Location(
reader.GetInt32("location_id"),
reader.GetInt32("parent_location"),
reader.GetInt32("address_fk"),
reader.GetValue(reader.GetOrdinal("designation")) as string,
reader.GetInt32("building"),
reader.GetInt32("room")
));
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
return Locations;
} }
public override List<Location> GetAll() public override List<Location> GetAll()
{ {
throw new System.NotImplementedException(); try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT {ColumnsForSelect} FROM {TableName}";
var reader = cmd.ExecuteReader();
while (reader.Read())
{
Locations.Add(new Location(
reader.GetInt32("location_id"),
reader.GetInt32("parent_location"),
reader.GetInt32("address_fk"),
reader.GetValue(reader.GetOrdinal("designation")) as string,
reader.GetInt32("building"),
reader.GetInt32("room")
));
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
return Locations;
}
public override void CallStoredProcedure(Location entity)
{
throw new System.NotSupportedException();
} }
public override Location GetSingle<P>(P pkValue) public override Location GetSingle<P>(P pkValue)
{ {
throw new System.NotImplementedException(); try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT {ColumnsForSelect} FROM {TableName} WHERE {PrimaryKeyFromTable} = {pkValue}";
var reader = cmd.ExecuteReader();
while (reader.Read())
{
_Locations = (new Location(
reader.GetInt32("location_id"),
reader.GetInt32("parent_location"),
reader.GetInt32("address_fk"),
reader.GetValue(reader.GetOrdinal("designation")) as string,
reader.GetInt32("building"),
reader.GetInt32("room")
));
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
return _Locations;
} }
public override void Update(Location entity) public override void Update(Location location)
{ {
throw new System.NotImplementedException(); try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText =
$"UPDATE {TableName} SET address_fk = {location.Id} , designation = '{location.Designation}', building = {location.BuildingNr} , room = {location.RoomNr} WHERE location_id = {location.Id}";
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
} }
} }
} }

View File

@ -1,54 +1,192 @@
using LoggingClient.Model; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
using MySql.Data.MySqlClient;
using LoggingClient.Model;
namespace LoggingClient.Repository namespace LoggingClient.Repository
{ {
class LoggingRepository : RepositoryBase<Logging> class LoggingRepository : RepositoryBase<Logging>
{ {
public override string TableName => throw new NotImplementedException(); public override string TableName => "v_logentries";
public override string ColumnsForSelect => "id, pod, location, hostname, severity, timestamp, message";
public override string ColumnsForAdd { get; }
public override string PrimaryKeyFromTable => "id";
public override void Add(Logging entity) public List<Logging> Logs { get; set; }
{ public Logging _Logs { get; set; }
throw new NotImplementedException();
}
public override long Count(string whereCondition, Dictionary<string, object> parameterValues) public LoggingRepository(string connectionString) : base(connectionString)
{ {
throw new NotImplementedException(); Logs = new List<Logging>();
}
public override long Count()
{
throw new NotImplementedException();
}
public override void Delete(Logging entity)
{
throw new NotImplementedException();
}
public override List<Logging> GetAll(string whereCondition, Dictionary<string, object> parameterValues)
{
throw new NotImplementedException();
}
public override List<Logging> GetAll()
{
throw new NotImplementedException();
} }
public override Logging GetSingle<P>(P pkValue) public override Logging GetSingle<P>(P pkValue)
{ {
throw new NotImplementedException(); try
} {
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT {ColumnsForSelect} FROM {TableName} WHERE {PrimaryKeyFromTable} = {pkValue}";
var reader = cmd.ExecuteReader();
while (reader.Read())
{
_Logs = (new Logging(
reader.GetInt32("id"),
reader.GetValue(reader.GetOrdinal("pod")) as string,
reader.GetValue(reader.GetOrdinal("location")) as string,
reader.GetValue(reader.GetOrdinal("hostname")) as string,
reader.GetInt32("severity"),
reader.GetDateTime("timestamp"),
reader.GetValue(reader.GetOrdinal("message")) as string
));
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
return _Logs;
}
public override void Add(Logging newLogging)
{
try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "LogMessageAdd";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@i_pod", MySqlDbType.String).Value = newLogging.Pod;
cmd.Parameters.Add("@i_hostname", MySqlDbType.String).Value = newLogging.Hostname;
cmd.Parameters.Add("@i_severity", MySqlDbType.Int32).Value = newLogging.Severity;
cmd.Parameters.Add("@i_message", MySqlDbType.String).Value = newLogging.Message;
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
}
public override void Delete(Logging entity)
{
throw new System.NotSupportedException();
}
public override void Update(Logging entity) public override void Update(Logging entity)
{ {
throw new NotImplementedException(); throw new System.NotSupportedException();
}
public override List<Logging> GetAll(string whereCondition, Dictionary<string, object> parameterValues)
{
var whereCon = whereCondition;
if (parameterValues.Count > 0 && whereCondition != null)
{
foreach (KeyValuePair<string, object> p in parameterValues)
{
whereCon = whereCon.Replace($"@{p.Key}", p.Value.ToString());
}
}
try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT {ColumnsForSelect} FROM {TableName} WHERE {whereCon}";
var reader = cmd.ExecuteReader();
while (reader.Read())
{
Logs.Add(new Logging(
reader.GetInt32("id"),
reader.GetValue(reader.GetOrdinal("pod")) as string,
reader.GetValue(reader.GetOrdinal("location")) as string,
reader.GetValue(reader.GetOrdinal("hostname")) as string,
reader.GetInt32("severity"),
reader.GetDateTime("timestamp"),
reader.GetValue(reader.GetOrdinal("message")) as string
));
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
return Logs;
}
public override List<Logging> GetAll()
{
try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = $"SELECT {ColumnsForSelect} FROM {TableName}";
var reader = cmd.ExecuteReader();
while (reader.Read())
{
Logs.Add(new Logging(
reader.GetInt32("id"),
reader.GetValue(reader.GetOrdinal("pod")) as string,
reader.GetValue(reader.GetOrdinal("location")) as string,
reader.GetValue(reader.GetOrdinal("hostname")) as string,
reader.GetInt32("severity"),
reader.GetDateTime("timestamp"),
reader.GetValue(reader.GetOrdinal("message")) as string
));
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
return Logs;
}
public override void CallStoredProcedure(Logging logModelEntry)
{
try
{
using (var conn = new MySqlConnection(ConnectionString))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "LogClear";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("_logentries_id", logModelEntry.Id);
cmd.ExecuteNonQuery();
}
}
}
catch (MySqlException ex)
{
MessageBox.Show(ex.ToString());
}
} }
} }
} }

View File

@ -1,22 +1,86 @@
using System; using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Windows;
using System.Threading.Tasks;
namespace LoggingClient.Repository namespace LoggingClient.Repository
{ {
public abstract class RepositoryBase<M> : IRepositoryBase<M> public abstract class RepositoryBase<M> : IRepositoryBase<M>
{ {
public abstract string TableName { get; } protected RepositoryBase(string connectionString)
{
this.ConnectionString = connectionString;
}
protected string ConnectionString { get; }
public abstract M GetSingle<P>(P pkValue);
public abstract void Add(M entity); public abstract void Add(M entity);
public abstract long Count(string whereCondition, Dictionary<string, object> parameterValues);
public abstract long Count();
public abstract void Delete(M entity); public abstract void Delete(M entity);
public abstract List<M> GetAll(string whereCondition, Dictionary<string, object> parameterValues);
public abstract List<M> GetAll();
public abstract M GetSingle<P>(P pkValue);
public abstract void Update(M entity); public abstract void Update(M entity);
public abstract List<M> GetAll(string whereCondition, Dictionary<string, object> parameterValues);
public abstract List<M> GetAll();
public abstract void CallStoredProcedure(M entity);
public IQueryable<M> Query(string whereCondition, Dictionary<string, object> parameterValues)
{
throw new System.NotSupportedException();
}
public long Count(string whereCondition, Dictionary<string, object> parameterValues)
{
var whereCon = whereCondition;
if (parameterValues.Count > 0 && whereCondition != null)
{
foreach (KeyValuePair<string, object> p in parameterValues)
{
whereCon = whereCon.Replace($"@{p.Key}", p.Value.ToString());
}
}
try
{
using (var conn = new MySqlConnection(this.ConnectionString))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = $"select count(*) from {this.TableName} where {whereCon}";
return (long)cmd.ExecuteScalar();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
return -1;
}
}
public long Count()
{
try
{
using (var conn = new MySqlConnection(this.ConnectionString))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = $"select count(*) from {this.TableName}";
return (long)cmd.ExecuteScalar();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
return -1;
}
}
public abstract string TableName { get; }
public abstract string ColumnsForSelect { get; }
public abstract string ColumnsForAdd { get; }
public abstract string PrimaryKeyFromTable { get; }
} }
} }

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfControlNugget.ViewModel.Commands
{
public class BaseCommand : ICommand
{
private Action<object> _method;
public event EventHandler CanExecuteChanged;
public BaseCommand(Action<object> method)
{
_method = method;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_method.Invoke(parameter);
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LoggingClient.Model;
namespace LoggingClient.ViewModel
{
public class LocationTreeBuilder
{
public Node<Location> BuildTree(List<Location> locations)
{
if (locations == null) return new Node<Location>();
var nodeList = locations.ToList();
var tree = FindTreeRoot(nodeList);
BuildTree(tree, nodeList);
return tree;
}
private void BuildTree(Node<Location> locationNode, List<Location> descendants)
{
var children = descendants.Where(node => node.ParentId == locationNode.ValueObject.Id).ToArray();
foreach (var child in children)
{
var branch = Map(child, locationNode);
locationNode.AddChildNode(branch);
descendants.Remove(child);
}
foreach (var branch in locationNode.ChildNodesList)
{
BuildTree(branch, descendants);
}
}
private Node<Location> FindTreeRoot(List<Location> nodes)
{
var rootNodes = nodes.Where(node => node.ParentId == 0);
if (rootNodes.Count() != 1) return new Node<Location>();
var rootNode = rootNodes.Single();
nodes.Remove(rootNode);
return Map(rootNode, null);
}
private Node<Location> Map(Location loc, Node<Location> parentNode)
{
return new Node<Location>
{
ValueObject = loc,
ParentNode = parentNode
};
}
}
}

View File

@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using LoggingClient.Model;
using LoggingClient.Repository;
using LoggingClient.ViewModel.Commands;
namespace LoggingClient.ViewModel
{
class LocationViewModel : INotifyPropertyChanged
{
private string _txtConnectionString;
private ICommand _btnLoadDataClick;
private ICommand _btnAddDataClick;
private ICommand _btnDeleteDataClick;
private ICommand _btnUpdateDataClick;
private ICommand _btnBuildTreeClick;
public List<Location> Locations
{
get => _locations;
set
{
_locations = value;
OnPropertyChanged("Locations");
}
}
private List<Location> _locations;
public Location NewLocationModelEntry { get; set; }
public List<Node<Location>> LocationTree { get; set; }
public LocationViewModel()
{
TxtConnectionString = "Server=localhost;Database=inventarisierungsloesung;Uid=root;Pwd=MySQLPassword1234!;";
Locations = new List<Location>();
NewLocationModelEntry = new Location();
}
public Logging MySelectedItem { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public string TxtConnectionString
{
get => _txtConnectionString;
set
{
_txtConnectionString = value;
OnPropertyChanged(nameof(TxtConnectionString));
}
}
public ICommand BtnLoadDataClick
{
get
{
return _btnLoadDataClick ?? (_btnLoadDataClick = new RelayCommand(
x =>
{
LoadData();
}));
}
}
public ICommand BtnAddDataClick
{
get
{
return _btnAddDataClick ?? (_btnAddDataClick = new RelayCommand(
x =>
{
AddData();
}));
}
}
public ICommand BtnDeleteDataClick
{
get
{
return _btnDeleteDataClick ?? (_btnDeleteDataClick = new RelayCommand(
x =>
{
DeleteData();
}));
}
}
public ICommand BtnUpdateDataClick
{
get
{
return _btnUpdateDataClick ?? (_btnUpdateDataClick = new RelayCommand(
x =>
{
UpdateData();
}));
}
}
public ICommand BtnBuildTreeClick
{
get
{
return _btnBuildTreeClick ?? (_btnBuildTreeClick = new RelayCommand(
x =>
{
LoadTreeData();
}));
}
}
private void LoadData()
{
try
{
var locationModelRepository = new LocationRepository(TxtConnectionString);
this.Locations = locationModelRepository.GetAll();
this.LocationTree = new List<Node<Location>>();
GenerateLocationTreeFromList(Locations);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LocationTree"));
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
}
private void AddData()
{
try
{
var locationModelRepository = new LocationRepository(TxtConnectionString);
locationModelRepository.Add(this.NewLocationModelEntry);
this.Locations = locationModelRepository.GetAll();
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
}
private void DeleteData()
{
try
{
var locationModelRepository = new LocationRepository(TxtConnectionString);
locationModelRepository.Delete(this.NewLocationModelEntry);
this.Locations = locationModelRepository.GetAll();
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
}
private void UpdateData()
{
try
{
var locationModelRepository = new LocationRepository(TxtConnectionString);
locationModelRepository.Update(this.NewLocationModelEntry);
this.Locations = locationModelRepository.GetAll();
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
}
private void LoadTreeData()
{
try
{
var locationModelRepository = new LocationRepository(TxtConnectionString);
this.Locations = locationModelRepository.GetAll();
this.LocationTree = new List<Node<Location>>();
GenerateLocationTreeFromList(Locations);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LocationTree"));
}
catch (Exception ex)
{
MessageBox.Show("Error occurred: " + ex.Message);
}
}
public void GenerateLocationTreeFromList(List<Location> locationList)
{
var treeBuilder = new LocationTreeBuilder();
var locationNode = treeBuilder.BuildTree(locationList);
this.LocationTree.Add(locationNode);
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@ -171,21 +171,15 @@ namespace LoggingClient.ViewModel
var reader = cmd.ExecuteReader(); var reader = cmd.ExecuteReader();
while (reader.Read()) while (reader.Read())
{ {
// ISDBNull Check because location can be NULL in Database
var location = "";
if (!reader.IsDBNull(reader.GetOrdinal("location")))
{
location = reader.GetString("location");
}
Logs.Add(new Logging( Logs.Add(new Logging(
reader.GetInt32("id"), reader.GetInt32(reader.GetOrdinal("id")),
reader.GetString("pod"), reader.GetValue(reader.GetOrdinal("pod")) as string,
location, reader.GetValue(reader.GetOrdinal("location")) as string,
reader.GetString("hostname"), reader.GetValue(reader.GetOrdinal("hostname")) as string,
reader.GetInt32("severity"), reader.GetInt32(reader.GetOrdinal("severity")),
reader.GetDateTime("timestamp"), reader.GetDateTime(reader.GetOrdinal("timestamp")),
reader.GetString("message") reader.GetValue(reader.GetOrdinal("message")) as string
)); )) ;
} }
} }
conn.Close(); conn.Close();

View File

@ -0,0 +1,46 @@
using LoggingClient.ViewModel;
using System.ComponentModel;
using System.Windows.Input;
using WpfControlNugget.ViewModel.Commands;
namespace WpfControlNugget.ViewModel
{
class NavigationViewModel : INotifyPropertyChanged
{
public ICommand LogsCommand { get; set; }
public ICommand LocationsCommand { get; set; }
private object _selectedViewModel;
public object SelectedViewModel
{
get => _selectedViewModel;
set { _selectedViewModel = value; OnPropertyChanged("SelectedViewModel"); }
}
public NavigationViewModel()
{
LogsCommand = new BaseCommand(OpenLogs);
LocationsCommand = new BaseCommand(OpenLocations);
}
private void OpenLogs(object obj)
{
SelectedViewModel = new LogViewModel();
}
private void OpenLocations(object obj)
{
SelectedViewModel = new LocationViewModel();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
}

View File

@ -0,0 +1,121 @@
<UserControl x:Class="LoggingClient.Views.LocationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:LoggingClient.Views"
xmlns:validators="clr-namespace:LoggingClient.Validators"
xmlns:viewModel="clr-namespace:LoggingClient.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<!--<Control.DataContext>
<viewModel:LocationViewModel/>
</Control.DataContext>-->
<Grid Height="450" Width="800" Background="#FF89A9B2" >
<TextBlock Height="32" HorizontalAlignment="Left" Margin="10,18,0,0" Name="TextBlockHeading" Text="Locations" VerticalAlignment="Top" Width="310" FontSize="20" FontStretch="Normal"/>
<Grid HorizontalAlignment="Left" Height="416" VerticalAlignment="Top" Width="773">
<DataGrid Validation.ErrorTemplate="{x:Null}" CanUserAddRows="False" AutoGenerateColumns="False" HorizontalAlignment="Left" SelectedItem="{Binding MySelectedItem, Mode=TwoWay}" Margin="10,196,0,76" Name="DataGridLocations" Width="763" ItemsSource="{Binding Path=Locations}" CanUserResizeRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Id}" Header="id" Width="1*" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=ParentId}" Header="ParentId" Width="1*" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=AddressId}" Header="AddressId" Width="1*" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=Designation}" Header="Designation" Width="1*" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=BuildingNr}" Header="BuildingNr" Width="1*" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=RoomNr}" Header="RoomNr" Width="1*" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
<TreeView Grid.Row="0" Margin="10,51,0,225" ItemsSource="{Binding LocationTree, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=true, Mode=TwoWay}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ChildNodesList, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=true, Mode=TwoWay}">
<TreeViewItem Header="{Binding}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<!--<Button Content="Load Tree" Height="25" HorizontalAlignment="Left" Margin="703,181,0,0" x:Name="BtnLoadTreeClick" VerticalAlignment="Top" Width="70" Command="{Binding BtnBuildTreeClick}" />-->
<Button Content="Add" Height="25" HorizontalAlignment="Left" Margin="478,366,0,0" Name="BtnAdd" VerticalAlignment="Top" Width="70" Command="{Binding BtnAddDataClick}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding Text.Length, ElementName=EnterDesignation, UpdateSourceTrigger=PropertyChanged}" Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding Text.Length, ElementName=EnterBuildingNr, UpdateSourceTrigger=PropertyChanged}" Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding Text.Length, ElementName=EnterRoomNr, UpdateSourceTrigger=PropertyChanged}" Value="0">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Content="Update" Height="25" HorizontalAlignment="Left" Margin="553,366,0,0" Name="BtnUpdateDataClick" VerticalAlignment="Top" Width="70" Command="{Binding BtnUpdateDataClick}" />
<Button Content="Load Data" Height="25" HorizontalAlignment="Left" Margin="628,366,0,0" Name="BtnLoadDataClick" VerticalAlignment="Top" Width="70" Command="{Binding BtnLoadDataClick}" />
<Button Content="Delete" Height="25" HorizontalAlignment="Left" Margin="703,366,0,0" Name="BtnDeleteDataClick" VerticalAlignment="Top" Width="70" Command="{Binding BtnDeleteDataClick}"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="248,22,0,0" TextWrapping="Wrap" Text="{Binding TxtConnectionString}" Name="TxtConnectionString" VerticalAlignment="Top" Width="525" />
<TextBox HorizontalAlignment="Left" Height="25" Margin="10,366,0,0" TextWrapping="Wrap" x:Name="LocationId" VerticalAlignment="Top" Width="80" >
<Binding Path="NewLocationModelEntry.AddressId" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:IntRangeValidationRule
MinimumLength="1" MaximumLength="10000"/>
</Binding.ValidationRules>
</Binding>
</TextBox>
<TextBox HorizontalAlignment="Left" Height="25" Margin="95,366,0,0" TextWrapping="Wrap" Name="EnterParentId" VerticalAlignment="Top" Width="80">
<TextBox.Text>
<Binding Path="NewLocationModelEntry.ParentId" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:IntRangeValidationRule
validators:MinimumLength="1" validators:MaximumLength="10000"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox HorizontalAlignment="Left" Height="25" Margin="180,366,0,0" TextWrapping="Wrap" Name="EnterDesignation" VerticalAlignment="Top" Width="80">
<TextBox.Text>
<Binding Path="NewLocationModelEntry.Designation" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:StringRangeValidationRule
validators:MinimumLength="1" validators:MaximumLength="45"
ErrorMessage="Designation must contain at least 1 characters up to 45" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox HorizontalAlignment="Left" Height="25" Margin="265,366,0,0" TextWrapping="Wrap" Name="EnterBuildingNr" VerticalAlignment="Top" Width="80">
<TextBox.Text>
<Binding Path="NewLocationModelEntry.BuildingNr" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:IntRangeValidationRule
validators:MinimumLength="1" validators:MaximumLength="10000"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox HorizontalAlignment="Left" Height="25" Margin="350,366,0,0" TextWrapping="Wrap" Name="EnterRoomNr" VerticalAlignment="Top" Width="80" >
<TextBox.Text>
<Binding Path="NewLocationModelEntry.RoomNr" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:IntRangeValidationRule
validators:MinimumLength="1" validators:MaximumLength="10000"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<!--<ComboBox x:Name="SeverityCombobox" DisplayMemberPath="Severity" SelectedValuePath="id" ItemsSource="{Binding SeverityComboBox}" SelectedValue="{Binding Path=Severity , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="240,359,470,66" Width="90" Height="25"/>-->
<Label Content="Database Connection" HorizontalAlignment="Left" Margin="118,22,0,0" VerticalAlignment="Top" Height="23" Width="125" Background="{x:Null}" RenderTransformOrigin="0.366,0.725"/>
<Label Content="LocationId" HorizontalAlignment="Left" Margin="10,340,0,0" VerticalAlignment="Top" Width="80" FontSize="12"/>
<Label Content="ParentId" HorizontalAlignment="Left" Margin="95,340,0,0" VerticalAlignment="Top" Width="80" FontSize="12"/>
<Label Content="Designation" HorizontalAlignment="Left" Margin="180,340,0,0" VerticalAlignment="Top" Width="80" FontSize="12"/>
<Label Content="BuildingNr" HorizontalAlignment="Left" Margin="265,340,0,0" VerticalAlignment="Top" Width="80" FontSize="12"/>
<Label Content="RoomNr" HorizontalAlignment="Left" Margin="350,340,0,0" VerticalAlignment="Top" Width="80" FontSize="12"/>
</Grid>
</Grid>
</UserControl>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace LoggingClient.Views
{
/// <summary>
/// Interaction logic for LocationView.xaml
/// </summary>
public partial class LocationView : UserControl
{
public LocationView()
{
InitializeComponent();
}
}
}

22
LoggingClient/LoggingClient/Views/LogView.xaml Normal file → Executable file
View File

@ -6,14 +6,14 @@
xmlns:local="clr-namespace:LoggingClient.Views" xmlns:local="clr-namespace:LoggingClient.Views"
xmlns:validators="clr-namespace:LoggingClient.Validators" xmlns:validators="clr-namespace:LoggingClient.Validators"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="425" d:DesignWidth="800">
<Grid Height="450" Width="800" Background="#FF89A9B2" > <Grid Width="800" Background="#FF89A9B2" >
<TextBlock Height="32" HorizontalAlignment="Left" Margin="10,18,0,0" Name="TextBlockHeading" <TextBlock Height="32" HorizontalAlignment="Left" Margin="10,18,0,0" Name="TextBlockHeading"
Text="LogReader" VerticalAlignment="Top" Width="310" FontSize="20" FontStretch="Normal"/> Text="LogReader" VerticalAlignment="Top" Width="310" FontSize="20" FontStretch="Normal"/>
<Grid HorizontalAlignment="Left" Height="416" VerticalAlignment="Top" Width="773"> <Grid HorizontalAlignment="Left" Height="425" VerticalAlignment="Top" Width="773">
<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" SelectedItem="{Binding MySelectedItem, Mode=TwoWay}" Margin="10,55,0,97" Name="DataGridCustomers" Width="780" ItemsSource="{Binding Path=Logs}" <DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" SelectedItem="{Binding MySelectedItem, Mode=TwoWay}" Margin="10,55,0,97" Name="DataGridCustomers" Width="780" ItemsSource="{Binding Path=Logs}"
CanUserResizeRows="False"> CanUserResizeRows="False">
<DataGrid.Columns> <DataGrid.Columns>
@ -29,10 +29,10 @@ CanUserResizeRows="False">
<Label Content="Database Connection" HorizontalAlignment="Left" Margin="118,22,0,0" VerticalAlignment="Top" Height="23" Width="125" Background="{x:Null}" RenderTransformOrigin="0.366,0.725"/> <Label Content="Database Connection" HorizontalAlignment="Left" Margin="118,22,0,0" VerticalAlignment="Top" Height="23" Width="125" Background="{x:Null}" RenderTransformOrigin="0.366,0.725"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="248,22,0,0" TextWrapping="Wrap" Text="{Binding TxtConnectionString}" Name="TxtConnectionString" VerticalAlignment="Top" Width="525" /> <TextBox HorizontalAlignment="Left" Height="23" Margin="248,22,0,0" TextWrapping="Wrap" Text="{Binding TxtConnectionString}" Name="TxtConnectionString" VerticalAlignment="Top" Width="525" />
<Button Content="Find duplicate" Height="25" HorizontalAlignment="Left" Margin="545,355,0,0" x:Name="BtnFindDuplicate" VerticalAlignment="Top" Width="78" Command="{Binding BtnFindDuplicateClick}" /> <Button Content="Find duplicate" Height="25" HorizontalAlignment="Left" Margin="545,380,0,0" x:Name="BtnFindDuplicate" VerticalAlignment="Top" Width="78" Command="{Binding BtnFindDuplicateClick}" />
<Button Content="Load Data" Height="25" HorizontalAlignment="Left" Margin="628,355,0,0" Name="Btnloaddata" VerticalAlignment="Top" Width="70" Command="{Binding BtnLoadDataClick}" /> <Button Content="Load Data" Height="25" HorizontalAlignment="Left" Margin="628,380,0,0" Name="Btnloaddata" VerticalAlignment="Top" Width="70" Command="{Binding BtnLoadDataClick}" />
<Button Content="Confirm" Height="25" HorizontalAlignment="Left" Margin="703,355,0,0" Name="BtnConfirm" VerticalAlignment="Top" Width="70" Command="{Binding BtnConfirmDataClick}"/> <Button Content="Confirm" Height="25" HorizontalAlignment="Left" Margin="703,380,0,0" Name="BtnConfirm" VerticalAlignment="Top" Width="70" Command="{Binding BtnConfirmDataClick}"/>
<Button Content="Add" Height="25" HorizontalAlignment="Left" Margin="470,355,0,0" Name="BtnAdd" VerticalAlignment="Top" Width="70" Command="{Binding BtnAddDataClick}"> <Button Content="Add" Height="25" HorizontalAlignment="Left" Margin="470,380,0,0" Name="BtnAdd" VerticalAlignment="Top" Width="70" Command="{Binding BtnAddDataClick}">
<Button.Style> <Button.Style>
<Style TargetType="{x:Type Button}"> <Style TargetType="{x:Type Button}">
<Style.Triggers> <Style.Triggers>
@ -52,7 +52,7 @@ CanUserResizeRows="False">
</Style> </Style>
</Button.Style> </Button.Style>
</Button> </Button>
<TextBox HorizontalAlignment="Left" Height="25" Margin="10,355,0,0" TextWrapping="Wrap" Name="EnterPod" VerticalAlignment="Top" Width="110"> <TextBox HorizontalAlignment="Left" Height="25" Margin="10,350,0,0" TextWrapping="Wrap" Name="EnterPod" VerticalAlignment="Top" Width="110">
<TextBox.Text> <TextBox.Text>
<Binding Path="EnterPod" UpdateSourceTrigger="PropertyChanged"> <Binding Path="EnterPod" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules> <Binding.ValidationRules>
@ -62,7 +62,7 @@ CanUserResizeRows="False">
</Binding> </Binding>
</TextBox.Text> </TextBox.Text>
</TextBox> </TextBox>
<TextBox HorizontalAlignment="Left" Height="25" Margin="125,355,0,0" TextWrapping="Wrap" Name="EnterHostname" VerticalAlignment="Top" Width="110"> <TextBox HorizontalAlignment="Left" Height="25" Margin="125,350,0,0" TextWrapping="Wrap" Name="EnterHostname" VerticalAlignment="Top" Width="110">
<TextBox.Text> <TextBox.Text>
<Binding Path="EnterHostname" UpdateSourceTrigger="PropertyChanged"> <Binding Path="EnterHostname" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules> <Binding.ValidationRules>
@ -72,7 +72,7 @@ CanUserResizeRows="False">
</Binding> </Binding>
</TextBox.Text> </TextBox.Text>
</TextBox> </TextBox>
<TextBox HorizontalAlignment="Left" Height="25" Margin="240,355,0,0" TextWrapping="Wrap" Name="EnterSeverity" VerticalAlignment="Top" Width="110" > <TextBox HorizontalAlignment="Left" Height="25" Margin="240,350,0,0" TextWrapping="Wrap" Name="EnterSeverity" VerticalAlignment="Top" Width="110" >
<TextBox.Text> <TextBox.Text>
<Binding Path="EnterSeverity" UpdateSourceTrigger="PropertyChanged"> <Binding Path="EnterSeverity" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules> <Binding.ValidationRules>
@ -81,7 +81,7 @@ CanUserResizeRows="False">
</Binding> </Binding>
</TextBox.Text> </TextBox.Text>
</TextBox> </TextBox>
<TextBox HorizontalAlignment="Left" Height="50" Margin="355,355,0,0" TextWrapping="Wrap" Name="EnterMessage" VerticalAlignment="Top" Width="110"> <TextBox HorizontalAlignment="Left" Height="25" Margin="355,350,0,0" TextWrapping="Wrap" Name="EnterMessage" VerticalAlignment="Top" Width="418" RenderTransformOrigin="0.5,0.5">
<TextBox.Text> <TextBox.Text>
<Binding Path="EnterMessage" UpdateSourceTrigger="PropertyChanged"> <Binding Path="EnterMessage" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules> <Binding.ValidationRules>