Aufgeräumt und mit Kommentaren versehen (KeyedCollection dabei eingebaut)

This commit is contained in:
mdn 2015-12-05 23:39:07 +01:00
parent 2b2f31371a
commit e272f62629
14 changed files with 242 additions and 305 deletions

View file

@ -7,7 +7,7 @@ namespace TimeScheduler.Common
/// Vorbereitung:
/// <code language="xaml">
/// &lt;FrameworkElement.Resources&gt;
/// &tl;c:BindingProxy x:Key="proxy" Data="{Binding}"&gt;
/// &lt;c:BindingProxy x:Key="proxy" Data="{Binding}"&gt;
/// &lt;/FrameworkElement.Resources&gt;
/// </code>
/// Verwendung an einer anderen Stelle:

View file

@ -1,32 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TimeScheduler.Common
{
/// <summary>Mathematische Funktionen</summary>
public static class MathUtil
{
public static int IncrementDecrementNumber(string num, int minValue, int maxVal, bool increment)
/// <summary>Verringert/Erhöht die Zahl</summary>
/// <param name="num">Nummer die verändert werden soll</param>
/// <param name="minValue">Minmal erlaubter Wert</param>
/// <param name="maxValue">Maximal erlaubter Wert</param>
/// <param name="increment">Veränderungsrichtung</param>
/// <returns>Der veränderte Wert</returns>
public static int IncrementDecrementNumber(string num, int minValue, int maxValue, bool increment)
{
int newNum = ValidateNumber(num, minValue, maxVal);
int newNum = ValidateNumber(num, minValue, maxValue);
if (increment)
newNum = Math.Min(newNum + 1, maxVal);
newNum = Math.Min(newNum + 1, maxValue);
else
newNum = Math.Max(newNum - 1, 0);
return newNum;
}
/// <summary>Prüft den Wert auf den gültigen Bereich</summary>
/// <param name="newNum">zu Prüfender Wert</param>
/// <param name="minValue">Minmal erlaubter Wert</param>
/// <param name="maxValue">Maximal erlaubter Wert</param>
/// <returns>Der Wert, wenn er im Bereich liegt, sonst der jeweilige Grenzwert, der überschriten wurde</returns>
public static int ValidateNumber(string newNum, int minValue, int maxValue)
{
int num;
if (!int.TryParse(newNum, out num))
return 0;
num = 0;
return ValidateNumber(num, minValue, maxValue);
}
/// <summary>Prüft den Wert auf den gültigen Bereich</summary>
/// <param name="newNum">zu Prüfender Wert</param>
/// <param name="minValue">Minmal erlaubter Wert</param>
/// <param name="maxValue">Maximal erlaubter Wert</param>
/// <returns>Der Wert, wenn er im Bereich liegt, sonst der jeweilige Grenzwert, der überschriten wurde</returns>
public static int ValidateNumber(int newNum, int minValue, int maxValue)
{
newNum = Math.Max(newNum, minValue);

View file

@ -1,20 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TimeScheduler.Model;
namespace TimeScheduler.Model
namespace TimeScheduler.Domain
{
/// <summary>Schnittstelle zum Provider der die Daten ermitteln</summary>
public interface IDomain
{
List<ITimeItem> GetItems(DateTime date);
/// <summary>Ermittelt die Werte für den angegebenen Tag</summary>
/// <param name="date">Der Tag für den Werte gesucht werden sollen</param>
/// <returns>Die Daten, für den angefragten Tag</returns>
IEnumerable<ITimeItem> GetItems(DateTime date);
/// <summary>Ermittelt die gültigen Kostenstellen</summary>
/// <returns>Liste der gültigen Kostenstellen</returns>
Dictionary<int, string> GetCostUnits();
void ElementAdded(ITimeItem timeItem);
/// <summary>Fügt ein neues Element hinzu</summary>
/// <param name="timeItem">Das neue Element</param>
int ElementAdded(ITimeItem timeItem);
/// <summary>Verändert ein vorhandenes Element</summary>
/// <param name="timeItem">die neuen Daten</param>
void ElementChanged(ITimeItem timeItem);
/// <summary>Entfernt ein Element</summary>
/// <param name="timeItem">Das zu entfernende Element</param>
void ElementRemoved(ITimeItem timeItem);
}
}

View file

@ -4,16 +4,16 @@ using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Linq;
using System.Reflection;
using TimeScheduler.Model;
namespace TimeScheduler.Model.Impl
namespace TimeScheduler.Domain.Impl
{
class FileDomain : IDomain
{
#region Konstruktion
private List<TimeItem> allItems_ = new List<TimeItem>();
private SimpleTimes allItems_ = new SimpleTimes();
private string filename_ = string.Empty;
private int lastKey_ = 0;
public FileDomain()
{
@ -25,13 +25,13 @@ namespace TimeScheduler.Model.Impl
else
{
// Wenn nichts vorhanden, dann einen Spielsatz anlegen
allItems_ = new List<TimeItem> {
new TimeItem { Description = "Desc 01", From = DateTime.Now.Subtract(TimeSpan.FromHours(2)), Till = DateTime.Now, CostUnit = 14, ItemType = TimeItemType.Normal },
new TimeItem { Description = "Desc 02", From = DateTime.Now.Subtract(TimeSpan.FromHours(2)), Till = DateTime.Now, CostUnit = 13, ItemType = TimeItemType.Break },
new TimeItem { Description = "Desc 03", From = DateTime.Now.Subtract(TimeSpan.FromHours(2)), Till = DateTime.Now, CostUnit = 12, ItemType = TimeItemType.Holiday },
new TimeItem { Description = "Desc 04", From = DateTime.Now.Subtract(TimeSpan.FromHours(2)), Till = DateTime.Now, CostUnit = 11, ItemType = TimeItemType.Ill },
new TimeItem { Description = "Desc 05", From = DateTime.Now.Subtract(TimeSpan.FromHours(2)), Till = DateTime.Now, CostUnit = 15, ItemType = TimeItemType.Normal },
};
allItems_.Add(new TimeItem("Desc 01", DateTime.Now.Date.Add(TimeSpan.FromHours(0)), DateTime.Now.Date.Add(TimeSpan.FromHours(1.5)), 11, TimeItemType.Normal, ++lastKey_));
allItems_.Add(new TimeItem("Desc 02", DateTime.Now.Date.Add(TimeSpan.FromHours(2)), DateTime.Now.Date.Add(TimeSpan.FromHours(3.5)), 12, TimeItemType.Break, ++lastKey_));
allItems_.Add(new TimeItem("Desc 03", DateTime.Now.Date.Add(TimeSpan.FromHours(4)), DateTime.Now.Date.Add(TimeSpan.FromHours(5.5)), 13, TimeItemType.Holiday, ++lastKey_));
allItems_.Add(new TimeItem("Desc 04", DateTime.Now.Date.Add(TimeSpan.FromHours(6)), DateTime.Now.Date.Add(TimeSpan.FromHours(7.5)), 14, TimeItemType.Ill, ++lastKey_));
allItems_.Add(new TimeItem("Desc 05", DateTime.Now.Date.Add(TimeSpan.FromHours(8)), DateTime.Now.Date.Add(TimeSpan.FromHours(9.5)), 15, TimeItemType.Normal, ++lastKey_));
// und direkt speichern
Save();
}
}
#endregion
@ -41,9 +41,9 @@ namespace TimeScheduler.Model.Impl
{
var bin = new BinaryFormatter();
using (var rd = new FileStream(filePath, FileMode.Open))
allItems_ = bin.Deserialize(rd) as List<TimeItem>;
//allItems_ = bin.Deserialize(rd) as List<TimeItem>;
allItems_ = bin.Deserialize(rd) as SimpleTimes;
}
private void WriteList(string path)
{
var bin = new BinaryFormatter();
@ -53,13 +53,15 @@ namespace TimeScheduler.Model.Impl
private void ReadListXml(string filePath)
{
var xs = new XmlSerializer(typeof(List<TimeItem>));
//var xs = new XmlSerializer(typeof(List<TimeItem>));
var xs = new XmlSerializer(typeof(SimpleTimes));
using (var rd = new StreamReader(filePath))
allItems_ = xs.Deserialize(rd) as List<TimeItem>;
allItems_ = xs.Deserialize(rd) as SimpleTimes;
}
private void WriteListXml(string path)
{
var xs = new XmlSerializer(typeof(List<TimeItem>));
//var xs = new XmlSerializer(typeof(List<TimeItem>));
var xs = new XmlSerializer(typeof(SimpleTimes));
using (StreamWriter wr = new StreamWriter(path))
xs.Serialize(wr, allItems_);
}
@ -67,8 +69,8 @@ namespace TimeScheduler.Model.Impl
private void Load()
{
ReadListXml(filename_);
lastKey_ = allItems_.Max(x => x.Key);
}
private void Save()
{
var newFilename = filename_ + ".new";
@ -79,13 +81,15 @@ namespace TimeScheduler.Model.Impl
#endregion
#region IDomain
public List<ITimeItem> GetItems(DateTime date)
IEnumerable<ITimeItem> IDomain.GetItems(DateTime date)
{
var founded = allItems_.Where(x => x.From.Date == date);
return founded.Cast<ITimeItem>().ToList();
return allItems_
.Where(x => x.From.Date == date)
.OrderBy(x => x.From)
.Cast<ITimeItem>();
}
public Dictionary<int, string> GetCostUnits()
Dictionary<int, string> IDomain.GetCostUnits()
{
return new Dictionary<int, string>
{
@ -99,20 +103,23 @@ namespace TimeScheduler.Model.Impl
};
}
public void ElementAdded(ITimeItem timeItem)
int IDomain.ElementAdded(ITimeItem timeItem)
{
allItems_.Add((TimeItem)timeItem);
var ti = new TimeItem(timeItem);
ti.Key = ++lastKey_;
allItems_.Add(ti);
Save();
return ti.Key;
}
void IDomain.ElementChanged(ITimeItem timeItem)
{
allItems_[timeItem.Key].Copy(timeItem);
Save();
}
public void ElementChanged(ITimeItem timeItem)
void IDomain.ElementRemoved(ITimeItem timeItem)
{
allItems_.Remove((TimeItem)timeItem);
allItems_.Add((TimeItem)timeItem);
Save();
}
public void ElementRemoved(ITimeItem timeItem)
{
allItems_.Remove((TimeItem)timeItem);
var removed = allItems_.Remove(timeItem.Key);
if (removed)
Save();
}
#endregion

View file

@ -0,0 +1,90 @@
using System;
using System.Collections.ObjectModel;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace TimeScheduler.Domain.Impl
{
/// <summary>Einfache Liste für die TimeItems</summary>
/// <remarks>
/// Implementierung der Schittstelle für die Xml-Serialisierung, weil es sonst zu Schlüsseln Fehler kommt.
/// Implementierung von: http://weblogs.asp.net/pwelter34/444961
/// </remarks>
[Serializable]
[XmlRoot("SimpleTimes")]
public class SimpleTimes : KeyedCollection<int, TimeItem>, IXmlSerializable
{
#region Konstruktor
/// <summary>Konstruktor</summary>
public SimpleTimes() { }
/// <inheritdoc/>
protected override int GetKeyForItem(TimeItem item) { return item.Key; }
#endregion
#region IXmlSerializable
/// <summary>Schema ermitteln</summary>
/// <returns><c>null</c> im Standard</returns>
public XmlSchema GetSchema() { return null; }
/// <summary>Liest die Elemente aus dem XML-Stream</summary>
/// <param name="reader">Der Steam-Leser</param>
public void ReadXml(XmlReader reader)
{
//var keySerializer = new XmlSerializer(typeof(int));
var valueSerializer = new XmlSerializer(typeof(TimeItem));
var wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
//reader.ReadStartElement("key");
//var key = (int)keySerializer.Deserialize(reader);
//reader.ReadEndElement();
reader.ReadStartElement("value");
var value = (TimeItem)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
Add(value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
/// <summary>Schreibt die Elemente in den XML-Stream</summary>
/// <param name="writer">Der Stream-Schreiber</param>
public void WriteXml(XmlWriter writer)
{
//var keySerializer = new XmlSerializer(typeof(int));
var valueSerializer = new XmlSerializer(typeof(TimeItem));
foreach (var key in Dictionary.Keys)
{
writer.WriteStartElement("item");
//writer.WriteStartElement("key");
//keySerializer.Serialize(writer, key);
//writer.WriteEndElement();
writer.WriteStartElement("value");
var value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
}

View file

@ -1,12 +1,11 @@
using System;
using System.Runtime.Serialization;
using TimeScheduler.Common;
using TimeScheduler.Model;
namespace TimeScheduler.Model.Impl
namespace TimeScheduler.Domain.Impl
{
/// <summary>
///
/// </summary>
/// <summary>Beinhaltet den Datenbestand eines Zeitelementes</summary>
/// <remarks>
/// <see cref="ISerializable"/> muss implementiert werden, damit die Daten über den BinarFormater serialisiert werden können.
/// Für den XmlSerializer müsste die Klasse auf Public gestellt werden, was nicht immer gewünscht ist
@ -14,7 +13,32 @@ namespace TimeScheduler.Model.Impl
[Serializable]
public class TimeItem : NotifyableObject, ITimeItem//, ISerializable
{
public TimeItem() { }
#region Konstruktion
/// <summary>Standard-Konstruktor</summary>
public TimeItem() { key_ = -1; }
/// <summary>Konstruktor</summary>
/// <param name="description">Beschreibung</param>
/// <param name="from">Von</param>
/// <param name="till">Bis</param>
/// <param name="costUnit">Kostenstelle</param>
/// <param name="itemType">Elementtyp</param>
/// <param name="key">Schlüssel</param>
public TimeItem(string description, DateTime from, DateTime till, int costUnit, TimeItemType itemType, int? key = null) : this()
{
description_ = description;
from_ = from;
till_ = till;
costUnit_ = costUnit;
itemType_ = itemType;
if (key.HasValue)
key_ = key.Value;
}
/// <summary>Kopier-Konstruktor</summary>
/// <param name="rhs">Element von dem kopiert wird</param>
public TimeItem(ITimeItem rhs) { Copy(rhs); Key = rhs.Key; }
#endregion
//#region ISerializable
//public TimeItem(SerializationInfo info, StreamingContext context)
@ -27,20 +51,42 @@ namespace TimeScheduler.Model.Impl
//}
//#endregion
#region Methoden
/// <summary>Kopiert die Werte der Eigenschaften auf diese Objekt, ohney Key</summary>
/// <param name="rhs">Objkt von em kopiert werden soll</param>
public void Copy(ITimeItem rhs)
{
Description = rhs.Description;
From = rhs.From;
Till = rhs.Till;
CostUnit = rhs.CostUnit;
ItemType = rhs.ItemType;
}
#endregion
#region ITimeItem
private int key_;
/// <inheritdoc/>
public int Key { get { return key_; } set { SetField(ref key_, value); } }
private string description_;
/// <inheritdoc/>
public string Description { get { return description_; } set { SetField(ref description_, value); } }
private DateTime from_;
/// <inheritdoc/>
public DateTime From { get { return from_; } set { SetField(ref from_, value); } }
private DateTime till_;
/// <inheritdoc/>
public DateTime Till { get { return till_; } set { SetField(ref till_, value); } }
private int costUnit_;
/// <inheritdoc/>
public int CostUnit { get { return costUnit_; } set { SetField(ref costUnit_, value); } }
private TimeItemType itemType_;
/// <inheritdoc/>
public TimeItemType ItemType { get { return itemType_; } set { SetField(ref itemType_, value); } }
#endregion
}

View file

@ -6,7 +6,7 @@
xmlns:local="clr-namespace:TimeScheduler"
xmlns:c="clr-namespace:TimeScheduler.Common"
xmlns:vm="clr-namespace:TimeScheduler.ViewModel"
xmlns:domain="clr-namespace:TimeScheduler.Model.Impl"
xmlns:domain="clr-namespace:TimeScheduler.Domain.Impl"
mc:Ignorable="d" Language="de"
Title="TimeSchedule" Height="350" Width="525">
<Window.DataContext>
@ -27,8 +27,7 @@
<DockPanel Grid.Column="0">
<DatePicker DockPanel.Dock="Top" Margin="5" SelectedDate="{Binding Path=CurrentDate}"/>
<ListBox x:Name="lbTimeElements" Margin="5" HorizontalContentAlignment="Stretch"
ItemsSource="{Binding TimeItems}" SelectedItem="{Binding SelectedTimeItem}"
>
ItemsSource="{Binding TimeItems}" SelectedItem="{Binding SelectedTimeItem}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background">

View file

@ -6,6 +6,9 @@ namespace TimeScheduler.Model
/// <summary>Beinhaltet die Definition eines Daten-Elementes, das eine Zeiteinheit aufnimmt</summary>
public interface ITimeItem : INotifyPropertyChanged
{
/// <summary>Eindeutiger Schlüssel, der ein Element identifizieren kann</summary>
int Key { get; set; }
/// <summary>Textuelle Beschreibung</summary>
string Description { get; set; }

View file

@ -1,71 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion: 4.0.30319.42000
//
// Änderungen an dieser Datei können fehlerhaftes Verhalten verursachen und gehen verloren, wenn
// der Code neu generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace TimeScheduler.Properties
{
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder-Klasse
// über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der Option /str erneut aus, oder erstellen Sie Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TimeScheduler.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenlookups, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View file

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace TimeScheduler.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View file

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View file

@ -24,6 +24,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\TimeScheduler.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -33,6 +34,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\TimeScheduler.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@ -60,6 +62,7 @@
<Compile Include="Domain\IDomain.cs" />
<Compile Include="Domain\Impl\FileDomain.cs" />
<Compile Include="Domain\Impl\TimeItem.cs" />
<Compile Include="Domain\Impl\SimpleTimes.cs" />
<Compile Include="Domain\TimeItemType.cs" />
<Compile Include="Model\ITimeItem.cs" />
<Compile Include="ViewModel\MainViewModel.cs" />
@ -82,24 +85,6 @@
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>

View file

@ -2,10 +2,9 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using TimeScheduler.Common;
using TimeScheduler.Domain;
using TimeScheduler.Model;
namespace TimeScheduler.ViewModel
@ -13,9 +12,8 @@ namespace TimeScheduler.ViewModel
class MainViewModel : NotifyableObject
{
#region Konstruktion
private bool inLoading_ = false;
/// <summary>Standard-Konstruktor</summary>
public MainViewModel() : this(new Model.Impl.FileDomain()) { Refresh(); }
public MainViewModel() : this(new Domain.Impl.FileDomain()) { Refresh(); }
/// <summary>Konstruktor</summary>
/// <param name="provider"></param>
@ -29,6 +27,7 @@ namespace TimeScheduler.ViewModel
CreateCommands();
}
/// <summary>Datenbeschaffer</summary>
protected IDomain Provider { get; private set; }
#endregion
@ -86,9 +85,16 @@ namespace TimeScheduler.ViewModel
// Laufende Datein belegen
var items = Provider.GetItems(date);
// Event abhängen, damit keine Änderungen an den Provider geschickt werden
TimeItems.CollectionChanged -= TimeItems_CollectionChanged;
try
{
inLoading_ = true;
// Event der Objekte entfernen
foreach (var item in TimeItems)
item.PropertyChanged -= Item_PropertyChanged;
// Elemente umlagern
TimeItems.Clear();
foreach (var item in items)
{
@ -96,7 +102,11 @@ namespace TimeScheduler.ViewModel
TimeItems.Add(item);
}
}
finally { inLoading_ = false; }
finally
{
// Event wieder anhängen
TimeItems.CollectionChanged += TimeItems_CollectionChanged;
}
SelectedTimeItem = TimeItems.FirstOrDefault();
}
@ -108,7 +118,7 @@ namespace TimeScheduler.ViewModel
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
foreach (ITimeItem item in e.NewItems)
Provider.ElementAdded(item);
item.Key = Provider.ElementAdded(item);
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{