This commit is contained in:
mdn 2015-12-04 07:47:13 +01:00
commit cc28b87b9f
24 changed files with 1139 additions and 0 deletions

29
.gitignore vendored Normal file
View file

@ -0,0 +1,29 @@
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*

View file

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TimeScheduler", "TimeScheduler\TimeScheduler.csproj", "{0129AAAE-40F7-4B87-959F-0C48806F496A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0129AAAE-40F7-4B87-959F-0C48806F496A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0129AAAE-40F7-4B87-959F-0C48806F496A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0129AAAE-40F7-4B87-959F-0C48806F496A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0129AAAE-40F7-4B87-959F-0C48806F496A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>

View file

@ -0,0 +1,9 @@
<Application x:Class="TimeScheduler.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TimeScheduler"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

View file

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace TimeScheduler
{
/// <summary>
/// Interaktionslogik für "App.xaml"
/// </summary>
public partial class App : Application
{
}
}

View file

@ -0,0 +1,38 @@
using System.Windows;
namespace TimeScheduler.Common
{
/// <summary>Hilfsklasse, mit der man in andere Datenkontexte greifen kann</summary>
/// <example>
/// Vorbereitung:
/// <code language="xaml">
/// &lt;FrameworkElement.Resources&gt;
/// &tl;c:BindingProxy x:Key="proxy" Data="{Binding}"&gt;
/// &lt;/FrameworkElement.Resources&gt;
/// </code>
/// Verwendung an einer anderen Stelle:
/// <code language="xaml">
/// &lt;FrameworkElement Property="{Binding Source={StaticResource proxy},Path=VMProperty}"&gt;
/// </code>
/// </example>
class BindingProxy : Freezable
{
#region Konstruktion
/// <summary>Standard-Konstruktor</summary>
public BindingProxy() { }
#endregion
#region Überschreibungen
/// <summary>Ermittelt das Hauptobjekt</summary>
/// <returns>Ein neues Hauptobjekt</returns>
protected override Freezable CreateInstanceCore() { return new BindingProxy(); }
#endregion
#region Eigenschaften
/// <summary>Getter/Setter für <see cref="DataProperty"/></summary>
public object Data { get { return GetValue(DataProperty); } set { SetValue(DataProperty, value); } }
/// <summary>Eigenschaft in der der Datenkontext gebunden wird</summary>
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
#endregion
}
}

View file

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TimeScheduler.Common
{
public static class MathUtil
{
public static int IncrementDecrementNumber(string num, int minValue, int maxVal, bool increment)
{
int newNum = ValidateNumber(num, minValue, maxVal);
if (increment)
newNum = Math.Min(newNum + 1, maxVal);
else
newNum = Math.Max(newNum - 1, 0);
return newNum;
}
public static int ValidateNumber(string newNum, int minValue, int maxValue)
{
int num;
if (!int.TryParse(newNum, out num))
return 0;
return ValidateNumber(num, minValue, maxValue);
}
public static int ValidateNumber(int newNum, int minValue, int maxValue)
{
newNum = Math.Max(newNum, minValue);
newNum = Math.Min(newNum, maxValue);
return newNum;
}
}
}

View file

@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace TimeScheduler.Common
{
/// <summary>Basis-Klasse für Objekte, die sich der Oberfläche mitteilen möchten</summary>
abstract class NotifyableObject : INotifyPropertyChanged
{
/// <summary>Setzt den neuen Wert auf das Feld, wenn sie unterschiedlich sind und wird das <see cref="PropertyChanged"/>-Ereignis</summary>
/// <typeparam name="T">Typ des Feldes</typeparam>
/// <param name="field">Verweis aufs Feld</param>
/// <param name="newValue">Neuer Wert</param>
/// <param name="propertyName">Name der Eigenschaft, die verändert wird</param>
/// <returns><c>Wahr</c>, wenn es ein neuer Wert ist, sonst <c>Falsch</c></returns>
protected bool SetField<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null)
{
// Wenn beide Werte gleich sind, dann nichts tun
if (object.Equals(field, newValue)) return false;
//if (Comparer<T>.Default.Compare(field, newValue) == 0) return false;
field = newValue;
OnPropertyChanged(propertyName);
return true;
}
/// <summary>Wirft das Ereignis <see cref="PropertyChanged"/></summary>
/// <param name="propertyName"></param>
protected void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>Ereignis um der Oberfläche mitzuteilen, dass sich eine Eigenschaft verändert hat</summary>
public event PropertyChangedEventHandler PropertyChanged;
}
}

View file

@ -0,0 +1,45 @@
using System;
using System.Windows.Input;
namespace TimeScheduler.Common
{
/// <summary>Proxy-Objekt zur <see cref="ICommand"/>-Schnittstelle</summary>
class RelayCommand : ICommand
{
#region Konstruktion
private Action execute_;
private Func<Boolean> canExecute_;
/// <summary>Konstruktor</summary>
/// <param name="execute">Auszuführende Funktion</param>
/// <param name="canExecute">Prüfung zum ausführen der Funktion</param>
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
if (execute == null) throw new ArgumentNullException("execute");
execute_ = execute;
canExecute_ = canExecute;
}
#endregion
#region ICommand
/// <summary>Wirft Ereignis, dass die Oberfläche die Prüfung zum ausführen erneut ruft</summary>
public void OnCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
handler(this, EventArgs.Empty);
}
public event EventHandler CanExecuteChanged;
/// <summary>Prüft ob das Kommando ausgeführt werden darf</summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter) { return canExecute_ == null ? true : canExecute_(); }
/// <summary>Wird gerufen um das Kommando ausführen</summary>
/// <param name="parameter"></param>
public void Execute(object parameter) { execute_(); }
#endregion
}
}

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TimeScheduler.Model
{
/// <summary>Schnittstelle zum Provider der die Daten ermitteln</summary>
public interface IDomain
{
List<ITimeItem> GetItems(DateTime date);
Dictionary<int, string> GetCostUnits();
void ElementAdded(ITimeItem timeItem);
void ElementChanged(ITimeItem timeItem);
void ElementRemoved(ITimeItem timeItem);
}
}

View file

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Linq;
namespace TimeScheduler.Model.Impl
{
class FileDomain : IDomain
{
#region Konstruktion
private List<ITimeItem> allItems_ = new List<ITimeItem>();
private string filename_ = string.Empty;
public FileDomain()
{
var fi = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location);
filename_ = Path.Combine(fi.DirectoryName, fi.Name + ".xmldata");
if (File.Exists(filename_))
ReadList(filename_);
else
{
// Wenn nichts vorhanden, dann einen Spielsatz anlegen
allItems_ = new List<ITimeItem> {
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 },
};
}
}
#endregion
#region Hilfsfunktionen
private void ReadList(string filePath)
{
var xs = new XmlSerializer(typeof(List<ITimeItem>));
var bin = new BinaryFormatter();
using (var rd = new StreamReader(filePath))
{
var elems = xs.Deserialize(rd) as List<ITimeItem>;
allItems_ = elems;
//allItems.Clear();
//foreach (var elem in elems)
// allItems.Add(elem);
}
}
private void WriteList(string path)
{
XmlSerializer xs = new XmlSerializer(typeof(List<TimeItem>));
var bin = new BinaryFormatter();
using (StreamWriter wr = new StreamWriter(path))
{
xs.Serialize(wr, (List<ITimeItem>)allItems_);
}
}
private void Save()
{
var newFilename = filename_ + ".new";
WriteList(newFilename);
File.Delete(filename_);
File.Move(newFilename, filename_);
}
#endregion
#region IDomain
public List<ITimeItem> GetItems(DateTime date)
{
var founded = allItems_.Where(x => x.From.Date == date);
return founded.ToList();
}
public Dictionary<int, string> GetCostUnits()
{
return new Dictionary<int, string>
{
{ 11, "Allgemein CC1" },
{ 12, "Allgemein CC2" },
{ 13, "Allgemein CC3" },
{ 14, "Allgemein IC4" },
{ 15, "Allgemein CC5" },
{ 16, "Allgemein CC6" },
{ 17, "Allgemein CC7" },
};
}
public void ElementAdded(ITimeItem timeItem)
{
allItems_.Add(timeItem);
Save();
}
public void ElementChanged(ITimeItem timeItem)
{
allItems_.Remove(timeItem);
allItems_.Add(timeItem);
Save();
}
public void ElementRemoved(ITimeItem timeItem)
{
allItems_.Remove(timeItem);
Save();
}
#endregion
}
}

View file

@ -0,0 +1,23 @@
using System;
using TimeScheduler.Common;
namespace TimeScheduler.Model.Impl
{
public class TimeItem : NotifyableObject, ITimeItem
{
private string description_;
public string Description { get { return description_; } set { SetField(ref description_, value); } }
private DateTime from_;
public DateTime From { get { return from_; } set { SetField(ref from_, value); } }
private DateTime till_;
public DateTime Till { get { return till_; } set { SetField(ref till_, value); } }
private int costUnit_;
public int CostUnit { get { return costUnit_; } set { SetField(ref costUnit_, value); } }
private TimeItemType itemType_;
public TimeItemType ItemType { get { return itemType_; } set { SetField(ref itemType_, value); } }
}
}

View file

@ -0,0 +1,15 @@
namespace TimeScheduler.Model
{
/// <summary>Typen, die ein <see cref="ITimeItem"/> sein kann</summary>
public enum TimeItemType : int
{
/// <summary>Normale Stundenerfassung</summary>
Normal = 0,
/// <summary>Pause</summary>
Break = 1,
/// <summary>Urlaub</summary>
Holiday = 2,
/// <summary>Krankheit</summary>
Ill = 3
}
}

View file

@ -0,0 +1,157 @@
<Window x:Class="TimeScheduler.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:TimeScheduler"
xmlns:c="clr-namespace:TimeScheduler.Common"
xmlns:vm="clr-namespace:TimeScheduler.ViewModel"
xmlns:domain="clr-namespace:TimeScheduler.Model.Impl"
mc:Ignorable="d" Language="de"
Title="TimeSchedule" Height="350" Width="525">
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<c:BindingProxy x:Key="proxy" Data="{Binding}"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<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}"
>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#FF00a0FF" Offset="0.5"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="showSelection" BorderBrush="Black" BorderThickness="1" Margin="1,2,1,0">
<Border Background="{TemplateBinding Background}" Margin="5" CornerRadius="10" Padding="5">
<ContentPresenter />
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="showSelection" Property="Background" Value="Blue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type domain:TimeItem}">
<StackPanel>
<TextBlock Text="{Binding Description}"/>
<TextBlock Text="{Binding From,StringFormat=g}" HorizontalAlignment="Right"/>
<TextBlock Text="{Binding Till,StringFormat=g}" HorizontalAlignment="Right"/>
<TextBlock Text="{Binding CostUnit}"/>
<TextBlock Text="{Binding ItemType}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ItemType}" Value="Break">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="GreenYellow" Offset="0.5"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ItemType}" Value="Holiday">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#FF99B4D1" Offset="0.5"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ItemType}" Value="Ill">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Green" Offset="0.5"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</DockPanel>
<ContentControl Grid.Column="1" Margin="5" Content="{Binding SelectedTimeItem}">
<ContentControl.ContentTemplate>
<DataTemplate DataType="{x:Type domain:TimeItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="15,10"/>
</Style>
<Style TargetType="DatePicker">
<Setter Property="Margin" Value="15,10"/>
</Style>
<Style TargetType="DatePickerTextBox">
<Setter Property="Margin" Value="15,10"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="Margin" Value="15,10"/>
</Style>
</Grid.Resources>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Von:"/>
<DatePickerTextBox Grid.Column="1" Grid.Row="0" Text="{Binding From,StringFormat=g}"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="Bis:"/>
<DatePickerTextBox Grid.Column="1" Grid.Row="1" Text="{Binding Till,StringFormat=g}"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Kostenstelle:"/>
<ComboBox Grid.Column="1" Grid.Row="2" DisplayMemberPath="Value" SelectedValuePath="Key"
ItemsSource="{Binding Source={StaticResource proxy},Path=Data.CostUnits}" SelectedValue="{Binding CostUnit}"/>
<TextBlock Grid.Column="0" Grid.Row="3" Text="Typ:"/>
<ComboBox Grid.Column="1" Grid.Row="3" DisplayMemberPath="Value" SelectedValuePath="Key"
ItemsSource="{Binding Source={StaticResource proxy},Path=Data.ItemTypes}" SelectedValue="{Binding ItemType}"/>
</Grid>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
</Window>

View file

@ -0,0 +1,11 @@
using System.Windows;
namespace TimeScheduler
{
/// <summary>Interaktionslogik für MainWindow.xaml</summary>
public partial class MainWindow : Window
{
/// <summary>Standard-Konstruktor</summary>
public MainWindow() { InitializeComponent(); }
}
}

View file

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TimeScheduler.Common;
namespace TimeScheduler.Model
{
abstract class ATimeItem : NotifyableObject, ITimeItem
{
}
}

View file

@ -0,0 +1,24 @@
using System;
using System.ComponentModel;
namespace TimeScheduler.Model
{
/// <summary>Beinhaltet die Definition eines Daten-Elementes, das eine Zeiteinheit aufnimmt</summary>
public interface ITimeItem : INotifyPropertyChanged
{
/// <summary>Textuelle Beschreibung</summary>
string Description { get; set; }
/// <summary>Startzeit</summary>
DateTime From { get; set; }
/// <summary>Endezeit</summary>
DateTime Till { get; set; }
/// <summary>Kostenstelle</summary>
int CostUnit { get; set; }
/// <summary>Typ</summary>
TimeItemType ItemType { get; set; }
}
}

View file

@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("TimeScheduler")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TimeScheduler")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
//Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie
//<UICulture>ImCodeVerwendeteKultur</UICulture> in der .csproj-Datei
//in einer <PropertyGroup> fest. Wenn Sie in den Quelldateien beispielsweise Deutsch
//(Deutschland) verwenden, legen Sie <UICulture> auf \"de-DE\" fest. Heben Sie dann die Auskommentierung
//des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile,
//sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher
//(wird verwendet, wenn eine Ressource auf der Seite
// oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.)
ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs
//(wird verwendet, wenn eine Ressource auf der Seite, in der Anwendung oder einem
// designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.)
)]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <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

@ -0,0 +1,117 @@
<?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

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <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

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

View file

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{0129AAAE-40F7-4B87-959F-0C48806F496A}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TimeScheduler</RootNamespace>
<AssemblyName>TimeScheduler</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Common\BindingProxy.cs" />
<Compile Include="Common\MathUtil.cs" />
<Compile Include="Domain\IDomain.cs" />
<Compile Include="Domain\Impl\FileDomain.cs" />
<Compile Include="Domain\Impl\TimeItem.cs" />
<Compile Include="Domain\TimeItemType.cs" />
<Compile Include="Model\ATimeItem.cs" />
<Compile Include="Model\ITimeItem.cs" />
<Compile Include="ViewModel\MainViewModel.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Common\RelayCommand.cs" />
<Compile Include="Common\NotifyableObject.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<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>
<None Include="App.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,126 @@
using System;
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.Model;
namespace TimeScheduler.ViewModel
{
class MainViewModel : NotifyableObject
{
#region Konstruktion
private bool inLoading_ = false;
/// <summary>Standard-Konstruktor</summary>
public MainViewModel() : this(new Model.Impl.FileDomain()) { Refresh(); }
/// <summary>Konstruktor</summary>
/// <param name="provider"></param>
public MainViewModel(IDomain provider)
{
Provider = provider;
TimeItems = new ObservableCollection<ITimeItem>();
TimeItems.CollectionChanged += TimeItems_CollectionChanged;
CreateCommands();
}
protected IDomain Provider { get; private set; }
#endregion
#region Eigenschaften
private DateTime currentDate_ = DateTime.Now.Date;
public DateTime CurrentDate
{
get { return currentDate_; }
set
{
if (SetField(ref currentDate_, value))
RefreshForDate(currentDate_);
}
}
private Dictionary<int, string> costUnits_;
public Dictionary<int, string> CostUnits { get { return costUnits_; } private set { SetField(ref costUnits_, value); } }
private Dictionary<TimeItemType, string> itemTypes_;
public Dictionary<TimeItemType, string> ItemTypes { get { return itemTypes_; } private set { SetField(ref itemTypes_, value); } }
private ObservableCollection<ITimeItem> timeItems_;
/// <summary>Beinhaltet die Elemente des aktuell ausgewählten Tages</summary>
public ObservableCollection<ITimeItem> TimeItems { get { return timeItems_; } private set { SetField(ref timeItems_, value); } }
private ITimeItem selectedTimeItem_;
/// <summary>Das aktuell selektierte Element, von dem weitere Details angezeigt werden sollen</summary>
public ITimeItem SelectedTimeItem { get { return selectedTimeItem_; } set { SetField(ref selectedTimeItem_, value); } }
#endregion
#region Kommandos
private void CreateCommands()
{
RefreshCommand = new RelayCommand(Refresh);
}
public ICommand RefreshCommand { get; private set; }
private void Refresh()
{
// Standardwerte belegen
CostUnits = Provider.GetCostUnits();
var it = new Dictionary<TimeItemType, string>();
foreach (TimeItemType tit in Enum.GetValues(typeof(TimeItemType)))
it[tit] = Enum.GetName(typeof(TimeItemType), tit);
ItemTypes = it;
// Andere Daten ermitteln
RefreshForDate(CurrentDate);
}
private void RefreshForDate(DateTime date)
{
foreach (var item in TimeItems)
item.PropertyChanged -= Item_PropertyChanged;
// Laufende Datein belegen
var items = Provider.GetItems(date);
try
{
inLoading_ = true;
TimeItems.Clear();
foreach (var item in items)
{
item.PropertyChanged += Item_PropertyChanged;
TimeItems.Add(item);
}
}
finally { inLoading_ = false; }
SelectedTimeItem = TimeItems.FirstOrDefault();
}
#endregion
#region Hilfsfunktionen
private void TimeItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
foreach (ITimeItem item in e.NewItems)
Provider.ElementAdded(item);
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
foreach (ITimeItem item in e.OldItems)
Provider.ElementRemoved(item);
}
}
private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
Provider.ElementChanged((ITimeItem)sender);
}
#endregion
}
}