HyperGraph
Добавлены обработчики расчета теорем, сохранения в файл результатов. Добавлена …
Changes
HyperGraphModel/Theorem.cs 28(+8 -20)
WPF/Common/Assets/Icon.ico 0(+0 -0)
WPF/Common/Helpers/IniFile.cs 2(+1 -1)
WPF/Common/Helpers/StatusBar.cs 2(+1 -1)
WPF/Common/Parameters/Parameter.cs 4(+2 -2)
WPF/Common/WPF/Dictionary.xaml 3(+2 -1)
WPF/Icon.ico 0(+0 -0)
WPF/Model/Calculate.cs 187(+96 -91)
WPF/Model/ObservableCollectionExtension.cs 57(+57 -0)
WPF/View/MainWindow.xaml 26(+21 -5)
WPF/ViewModel/MainViewModel.cs 126(+108 -18)
WPF/WPF.csproj 11(+8 -3)
Details
HyperGraphModel/Theorem.cs 28(+8 -20)
diff --git a/HyperGraphModel/Theorem.cs b/HyperGraphModel/Theorem.cs
index b94bf2a..ee5137e 100644
--- a/HyperGraphModel/Theorem.cs
+++ b/HyperGraphModel/Theorem.cs
@@ -25,19 +25,13 @@ namespace HyperGraphModel
{
if (Theorem.isEqualNumberOfVertices(Graph))
{
- return new TheoremAuto
- {
- isSatisfyTheorem = false,
- CountAutomorphism = 0,
- AutomorphismNodes = null,
- GraphWithoutAutoEdges = null
- };
+ return default;
}
// Копирую гипер-граф, чтобы не изменять исходный
HyperGraph graph = new HyperGraph(Graph);
// Число автоморфизмов
- Int64 count;
+ long count;
// Список вершин 0-ого гипер-ребра
List<string> intersect = new List<string>(graph.HyperEdge[0]);
@@ -79,19 +73,13 @@ namespace HyperGraphModel
{
if (!Theorem.isEqualNumberOfVertices(Graph))
{
- return new TheoremAuto
- {
- isSatisfyTheorem = false,
- CountAutomorphism = 0,
- AutomorphismNodes = null,
- GraphWithoutAutoEdges = null
- };
+ return default;
}
// Копирую гипер-граф, чтобы не изменять исходный
HyperGraph graph = new HyperGraph(Graph);
// Число автоморфизмов
- Int64 count = 1;
+ long count = 1;
// Список вершин 0-ого гипер-ребра
List<string> intersect = new List<string>(graph.HyperEdge[0]);
@@ -151,7 +139,7 @@ namespace HyperGraphModel
}
- private static Int64 Factorial(int input)
+ private static long Factorial(int input)
{
// Предрассчитанные значения
switch (input)
@@ -167,7 +155,7 @@ namespace HyperGraphModel
break;
}
int x;
- Int64 fact = 1;
+ long fact = 1;
try
{
// Вдруг выйдем за пределы максимального значения
@@ -183,11 +171,11 @@ namespace HyperGraphModel
return fact;
}
- private static Int64 Pow(Int64 input, Int64 grade)
+ private static long Pow(long input, long grade)
{
if (grade < 0)
throw new Exception("error");
- Int64 result = 1;
+ long result = 1;
for (int i = 0; i < grade; i++)
result *= input;
return result;
WPF/Common/Assets/Icon.ico 0(+0 -0)
diff --git a/WPF/Common/Assets/Icon.ico b/WPF/Common/Assets/Icon.ico
new file mode 100644
index 0000000..7ed5cb2
Binary files /dev/null and b/WPF/Common/Assets/Icon.ico differ
WPF/Common/Helpers/IniFile.cs 2(+1 -1)
diff --git a/WPF/Common/Helpers/IniFile.cs b/WPF/Common/Helpers/IniFile.cs
index e376ada..aad574f 100644
--- a/WPF/Common/Helpers/IniFile.cs
+++ b/WPF/Common/Helpers/IniFile.cs
@@ -53,7 +53,7 @@ namespace Common.Helpers
{
var value = Read(key, section).Split(new[] {"###"}, StringSplitOptions.None);
if (value.Length >= position &&
- (!isNumber || (Double.TryParse(value[position], NumberStyles.Any, CultureInfo.InvariantCulture, out doubVal) || (int.TryParse(value[position], out intVal)))))
+ (!isNumber || (double.TryParse(value[position], NumberStyles.Any, CultureInfo.InvariantCulture, out doubVal) || (int.TryParse(value[position], out intVal)))))
rezult.Add(key, value[position]);
}
return rezult;
WPF/Common/Helpers/StatusBar.cs 2(+1 -1)
diff --git a/WPF/Common/Helpers/StatusBar.cs b/WPF/Common/Helpers/StatusBar.cs
index fcb1160..af1c81f 100644
--- a/WPF/Common/Helpers/StatusBar.cs
+++ b/WPF/Common/Helpers/StatusBar.cs
@@ -25,7 +25,7 @@ namespace Common.Helpers
{
IsVisible = false;
Status = Status.Default;
- Message = String.Empty;
+ Message = string.Empty;
}
private Status _status;
WPF/Common/Parameters/Parameter.cs 4(+2 -2)
diff --git a/WPF/Common/Parameters/Parameter.cs b/WPF/Common/Parameters/Parameter.cs
index f7f7317..ea341ec 100644
--- a/WPF/Common/Parameters/Parameter.cs
+++ b/WPF/Common/Parameters/Parameter.cs
@@ -15,7 +15,7 @@ namespace Common.Parameters
protected Parameter()
{
Status = Status.Normal;
- ErrorShortDescr = String.Empty;
+ ErrorShortDescr = string.Empty;
IsVisible = true;
IsEnabled = true;
}
@@ -45,7 +45,7 @@ namespace Common.Parameters
public string ErrorShortDescr { get; set; }
public void ResetValidation()
{
- ErrorShortDescr = String.Empty;
+ ErrorShortDescr = string.Empty;
ErrorCount = 0;
ErrorWarningCount = 0;
ErrorMessage = null;
diff --git a/WPF/Common/WPF/Controls/TreeGridViewRowPresenter.cs b/WPF/Common/WPF/Controls/TreeGridViewRowPresenter.cs
index d83c29e..b65d307 100644
--- a/WPF/Common/WPF/Controls/TreeGridViewRowPresenter.cs
+++ b/WPF/Common/WPF/Controls/TreeGridViewRowPresenter.cs
@@ -11,7 +11,7 @@ namespace Common.WPF.Controls
{
public class TreeGridViewRowPresenter : GridViewRowPresenter
{
- public static DependencyProperty FirstColumnIndentProperty = DependencyProperty.Register("FirstColumnIndent", typeof(Double), typeof(TreeGridViewRowPresenter), new PropertyMetadata(0d));
+ public static DependencyProperty FirstColumnIndentProperty = DependencyProperty.Register("FirstColumnIndent", typeof(double), typeof(TreeGridViewRowPresenter), new PropertyMetadata(0d));
public static DependencyProperty ExpanderProperty = DependencyProperty.Register("Expander", typeof(UIElement), typeof(TreeGridViewRowPresenter), new FrameworkPropertyMetadata(null, OnExpanderChanged));
UIElementCollection _childs;
@@ -26,9 +26,9 @@ namespace Common.WPF.Controls
dpd?.AddValueChanged(this, (s, e) => EnsureLines());
}
- public Double FirstColumnIndent
+ public double FirstColumnIndent
{
- get { return (Double)GetValue(FirstColumnIndentProperty); }
+ get { return (double)GetValue(FirstColumnIndentProperty); }
set { SetValue(FirstColumnIndentProperty, value); }
}
@@ -106,7 +106,7 @@ namespace Common.WPF.Controls
UIElement uiColumn = (UIElement)base.GetVisualChild((int)_actualIndexProperty.GetValue(column, null));
// Compute column width
- double w = Math.Min(max, Double.IsNaN(column.Width) ? (double)_desiredWidthProperty.GetValue(column, null) : column.Width);
+ double w = Math.Min(max, double.IsNaN(column.Width) ? (double)_desiredWidthProperty.GetValue(column, null) : column.Width);
// First column indent
Rect rect;
diff --git a/WPF/Common/WPF/Converters/LevelToIndentConverter.cs b/WPF/Common/WPF/Converters/LevelToIndentConverter.cs
index b2c08e5..d7297ea 100644
--- a/WPF/Common/WPF/Converters/LevelToIndentConverter.cs
+++ b/WPF/Common/WPF/Converters/LevelToIndentConverter.cs
@@ -12,9 +12,9 @@ namespace Common.WPF.Converters
{
public object Convert(object o, Type type, object parameter, CultureInfo culture)
{
- Double indentSize = 5;
+ double indentSize = 5;
if (parameter != null)
- Double.TryParse(parameter.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out indentSize);
+ double.TryParse(parameter.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out indentSize);
return (int)o * indentSize + " 0 0 0";
}
WPF/Common/WPF/Dictionary.xaml 3(+2 -1)
diff --git a/WPF/Common/WPF/Dictionary.xaml b/WPF/Common/WPF/Dictionary.xaml
index 9eba151..9ead7c0 100644
--- a/WPF/Common/WPF/Dictionary.xaml
+++ b/WPF/Common/WPF/Dictionary.xaml
@@ -7,10 +7,11 @@
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<converters:EnumToDescriptionConverter x:Key="EnumToDescriptionConverter"/>
<converters:InversedBoolToVisibilityConverter x:Key="InversedBoolToVisibilityConverter"/>
+ <converters:StatusToColorConverter x:Key="StatusToColorConverter"/>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource DefaultButton}"/>
- <!--<BitmapImage x:Key="MainIcon" UriSource="pack://application:,,,/PasswordApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null;component/storage.ico" />-->
+ <BitmapImage x:Key="MainIcon" UriSource="pack://application:,,,/WPF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null;component/Common/Assets/Icon.ico" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style/TextBlockStyle.xaml" />
WPF/Icon.ico 0(+0 -0)
diff --git a/WPF/Icon.ico b/WPF/Icon.ico
new file mode 100644
index 0000000..7ed5cb2
Binary files /dev/null and b/WPF/Icon.ico differ
WPF/Model/Calculate.cs 187(+96 -91)
diff --git a/WPF/Model/Calculate.cs b/WPF/Model/Calculate.cs
index dc9ae1b..a6bc93c 100644
--- a/WPF/Model/Calculate.cs
+++ b/WPF/Model/Calculate.cs
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using WPF.ViewModel;
+using System.IO;
using HyperGraphModel;
using TheoremAuto = HyperGraphModel.Theorem.TheoremAuto;
@@ -15,25 +15,33 @@ namespace WPF.Model
public static void CreateGraph(int Edges, int SameVert, List<int> Verticies)
{
- var vert = Verticies.Sum(x => x - SameVert) + SameVert;
- var matrix = new Matrix<int>(vert, Edges);
-
- // заполнение ребер отдельными вершинами
- for (int j = 0, i = 0; j < Verticies.Count; j++)
+ try
{
- int k = 0;
- while (Verticies[j] - SameVert > k)
+ var vert = Verticies.Sum(x => x - SameVert) + SameVert;
+ var matrix = new Matrix<int>(vert, Edges);
+
+ // заполнение ребер отдельными вершинами
+ for (int j = 0, i = 0; j < Verticies.Count; j++)
{
- matrix[i++, j] = 1;
- k++;
+ int k = 0;
+ while (Verticies[j] - SameVert > k)
+ {
+ matrix[i++, j] = 1;
+ k++;
+ }
}
- }
- // заполнение ребер общими вершинами
- for (int i = vert - SameVert; i < vert; i++)
- for (int j = 0; j < matrix.countColumn; j++)
- matrix[i, j] = 1;
+ // заполнение ребер общими вершинами
+ for (int i = vert - SameVert; i < vert; i++)
+ for (int j = 0; j < matrix.countColumn; j++)
+ matrix[i, j] = 1;
- Graph = new HyperGraph(matrix);
+ Graph = new HyperGraph(matrix);
+ }
+ catch (Exception e)
+ {
+ MainViewModel.Current.Status = Common.Status.Error;
+ MainViewModel.Current.StatusMessage = e.Message;
+ }
}
public static TheoremAuto TheoremSecond()
@@ -43,20 +51,13 @@ namespace WPF.Model
if (Graph == null)
throw new Exception("Гипер граф не существует");
- var result = Theorem.TheoremAutomorphism(Graph);
- ExampleTheorema(Graph, output);
-
- return result;
+ return Theorem.TheoremAutomorphism(Graph);
}
catch (Exception e)
{
- return new TheoremAuto
- {
- AutomorphismNodes = null,
- isSatisfyTheorem = false,
- CountAutomorphism = 0,
- GraphWithoutAutoEdges = null
- };
+ MainViewModel.Current.Status = Common.Status.Error;
+ MainViewModel.Current.StatusMessage = e.Message;
+ return default;
}
}
@@ -67,76 +68,50 @@ namespace WPF.Model
if (Graph == null)
throw new Exception("Гипер граф не существует");
- var result = Theorem.TheoremAutomorphismForEqualNumberOfVertices(Graph);
- ExampleTheoremaThird(Graph, output);
-
- return result;
+ return Theorem.TheoremAutomorphismForEqualNumberOfVertices(Graph);
}
catch (Exception e)
{
- return new TheoremAuto
- {
- AutomorphismNodes = null,
- isSatisfyTheorem = false,
- CountAutomorphism = 0,
- GraphWithoutAutoEdges = null
- };
+ MainViewModel.Current.Status = Common.Status.Error;
+ MainViewModel.Current.StatusMessage = e.Message;
+ return default;
}
}
- #region Private методы
-
- // Все перестановки графа вывести в файл
- static void ExampleAllTranspos(HyperGraph graph, System.IO.StreamWriter output)
+ public static MemoryStream Export(TheoremAuto result, EnumTheorem theorem)
{
- // Массив (лист) всех возможных перестановок одного множества (гипер-ребра)
- List<List<string>> transpos;
-
- // Обработать все гипер-ребра
- for (int i = 0; i < graph.HyperEdge.Count; i++)
+ MemoryStream memoryStream = new MemoryStream();
+ switch (theorem)
{
- // Получить массив перестановок текущего гипер-ребра
- transpos = Combinatorics<string>.Transposition(graph.HyperEdge[i]);
-
- // Вывод всех вершин текущего гипер-ребра
- output.Write("Текущее ребро включает вершины:");
- for (int g = 0; g < graph.HyperEdge[i].Count; g++)
- {
- output.Write(" {0}", graph.HyperEdge[i][g]);
- }
-
- // Вывод всех перестановок текущего гипер-ребра
- output.WriteLine();
-
- // Вывод начальной перестановки
- output.Write("1:");
- for (int g = 0; g < graph.HyperEdge[i].Count; g++)
- {
- output.Write(" {0}", graph.HyperEdge[i][g]);
- }
-
- output.WriteLine("\r\n\t-----------");
- // Алгоритм перестановок не учитывает начальную, а начинает со следующей
- for (int g = 0; g < transpos.Count; g++)
- {
- output.Write("{0}: ", g + 2);
- for (int f = 0; f < transpos[g].Count; f++)
+ case EnumTheorem.Second:
{
- output.Write("{0} ", transpos[g][f]);
+ using (StreamWriter sw = new StreamWriter(memoryStream))
+ {
+ ExportTheoremaSecond(result, sw);
+ }
+ break;
}
+ case EnumTheorem.Third:
+ {
+ using (StreamWriter sw = new StreamWriter(memoryStream))
+ {
+ ExportTheoremaThird(result, sw);
+ }
+ break;
+ }
+ case EnumTheorem.Forth:
+ {
- output.WriteLine("\r\n\t-----------");
- }
- output.WriteLine();
+ break;
+ }
}
+ return memoryStream;
}
- // Найти общие вершины для всех гипер-ребер, подсчитать количество автоморфизмов гипер-графа и вывести все перестановки оставшихся ребер
- static void ExampleTheorema(HyperGraph graph, System.IO.StreamWriter output)
- {
- // Получить результат вычислений
- var result = Theorem.TheoremAutomorphism(graph);
+ #region Private методы
+ static void ExportTheoremaSecond(TheoremAuto result, StreamWriter output)
+ {
// Выполняется ли условие согласно теореме 2
output.WriteLine("Согласно теореме 2: " + result.isSatisfyTheorem);
// Если да, то вывести
@@ -174,18 +149,48 @@ namespace WPF.Model
output.WriteLine("\r\nКоличество автоморфизмов: " + result.CountAutomorphism + "\r\n");
- // Вывести перестановки в файл
- ExampleAllTranspos(result.GraphWithoutAutoEdges, output);
+ // Обработать все гипер-ребра
+ for (int i = 0; i < result.GraphWithoutAutoEdges.HyperEdge.Count; i++)
+ {
+ // Получить массив перестановок текущего гипер-ребра
+ transpos = Combinatorics<string>.Transposition(result.GraphWithoutAutoEdges.HyperEdge[i]);
+
+ // Вывод всех вершин текущего гипер-ребра
+ output.Write("Текущее ребро включает вершины:");
+ for (int g = 0; g < result.GraphWithoutAutoEdges.HyperEdge[i].Count; g++)
+ {
+ output.Write(" {0}", result.GraphWithoutAutoEdges.HyperEdge[i][g]);
+ }
+
+ // Вывод всех перестановок текущего гипер-ребра
+ output.WriteLine();
+
+ // Вывод начальной перестановки
+ output.Write("1:");
+ for (int g = 0; g < result.GraphWithoutAutoEdges.HyperEdge[i].Count; g++)
+ {
+ output.Write(" {0}", result.GraphWithoutAutoEdges.HyperEdge[i][g]);
+ }
+
+ output.WriteLine("\r\n\t-----------");
+ // Алгоритм перестановок не учитывает начальную, а начинает со следующей
+ for (int g = 0; g < transpos.Count; g++)
+ {
+ output.Write("{0}: ", g + 2);
+ for (int f = 0; f < transpos[g].Count; f++)
+ {
+ output.Write("{0} ", transpos[g][f]);
+ }
+
+ output.WriteLine("\r\n\t-----------");
+ }
+ output.WriteLine();
+ }
}
- // Уничтожить временный граф
- result.GraphWithoutAutoEdges.Dispose();
}
- static void ExampleTheoremaThird(HyperGraph Graph, System.IO.StreamWriter output)
+ static void ExportTheoremaThird(TheoremAuto result, StreamWriter output)
{
- // Подсчет количества и получение гипер-графа без общих вершин
- var result = Theorem.TheoremAutomorphismForEqualNumberOfVertices(Graph);
-
// Выполняется ли условие согласно теореме 3
output.WriteLine("Согласно теореме 3: " + result.isSatisfyTheorem);
// Если да, то вывести
WPF/Model/ObservableCollectionExtension.cs 57(+57 -0)
diff --git a/WPF/Model/ObservableCollectionExtension.cs b/WPF/Model/ObservableCollectionExtension.cs
new file mode 100644
index 0000000..1a9b085
--- /dev/null
+++ b/WPF/Model/ObservableCollectionExtension.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+
+namespace WPF.Model
+{
+
+ public static class ObservableCollectionExtension
+ {
+ public static void NotifyPropertyChanged<T>(this ObservableCollection<T> observableCollection, Action<T, PropertyChangedEventArgs> callBackAction)
+ where T : INotifyPropertyChanged
+ {
+ observableCollection.CollectionChanged += (sender, args) =>
+ {
+ //Does not prevent garbage collection says: http://stackoverflow.com/questions/298261/do-event-handlers-stop-garbage-collection-from-occuring
+ //publisher.SomeEvent += target.SomeHandler;
+ //then "publisher" will keep "target" alive, but "target" will not keep "publisher" alive.
+
+ //if (args.NewItems == null)
+ // return;
+ //foreach (T item in args.NewItems)
+ //{
+ // item.PropertyChanged += (obj, eventArgs) =>
+ // {
+ // callBackAction((T)obj, eventArgs);
+ // };
+ //}
+
+ if (args.OldItems != null)
+ foreach (T item in args.OldItems)
+ if (item != null && item is INotifyPropertyChanged i)
+ i.PropertyChanged -= (obj, eventArgs) =>
+ {
+ callBackAction((T)obj, eventArgs);
+ };
+
+
+ if (args.NewItems != null)
+ foreach (T item in args.NewItems)
+ if (item != null && item is INotifyPropertyChanged i)
+ {
+ i.PropertyChanged -= (obj, eventArgs) =>
+ {
+ callBackAction((T)obj, eventArgs);
+ };
+
+ i.PropertyChanged += (obj, eventArgs) =>
+ {
+ callBackAction((T)obj, eventArgs);
+ };
+ };
+
+ };
+ }
+ }
+}
WPF/View/MainWindow.xaml 26(+21 -5)
diff --git a/WPF/View/MainWindow.xaml b/WPF/View/MainWindow.xaml
index e251923..3998e73 100644
--- a/WPF/View/MainWindow.xaml
+++ b/WPF/View/MainWindow.xaml
@@ -13,13 +13,14 @@
x:Name="Window"
WindowState="{Binding WindowState}"
Background="{StaticResource WindowBackground}"
+ Icon="{StaticResource MainIcon}"
WindowStyle="None"
ResizeMode="CanResizeWithGrip"
AllowsTransparency="True"
Loaded="Window_Loaded"
Title="{Binding TitleText}"
- Height="215" Width="725"
- MinHeight="215" MinWidth="725"
+ Height="235" Width="725"
+ MinHeight="235" MinWidth="725"
BorderBrush="#FF494957"
BorderThickness="1">
<Window.Resources>
@@ -51,8 +52,9 @@
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
+ <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="{StaticResource WindowBackground}" x:Name="Header">
@@ -218,10 +220,24 @@
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding AutomorphismCount}" Margin="5 0" VerticalAlignment="Bottom" TextAlignment="Center" FontWeight="Bold" FontSize="18" Foreground="{StaticResource Yellow}" MinWidth="100"/>
</Grid>
-
-
+
+
</Grid>
+ <StackPanel Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{Binding Status, Converter={StaticResource StatusToColorConverter}}" Margin="0,1,0,0">
+ <TextBlock Text="{Binding StatusMessage}" FontSize="16" VerticalAlignment="Center" Margin="5 3 0 0" />
+
+ <!--<StackPanel.Style>
+ <Style TargetType="StackPanel">
+ <Setter Property="Visibility" Value="Visible"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="{x:Static status:Status.Normal}">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </StackPanel.Style>-->
+ </StackPanel>
</Grid>
</Window>
WPF/ViewModel/MainViewModel.cs 126(+108 -18)
diff --git a/WPF/ViewModel/MainViewModel.cs b/WPF/ViewModel/MainViewModel.cs
index e833ced..1a7b864 100644
--- a/WPF/ViewModel/MainViewModel.cs
+++ b/WPF/ViewModel/MainViewModel.cs
@@ -1,4 +1,5 @@
using Common.WPF;
+using Common;
//using WPF.Helpers;
using WPF.Model;
using System;
@@ -6,7 +7,8 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
+using System.ComponentModel;
+using System.Windows.Forms;
using Visibility = System.Windows.Visibility;
using TheoremAuto = HyperGraphModel.Theorem.TheoremAuto;
using static WPF.Model.Calculate;
@@ -17,26 +19,43 @@ namespace WPF.ViewModel
{
public MainViewModel() : base()
{
+ Current = this;
+
Verticies = new ObservableCollection<VertViewModel>();
+ Verticies.NotifyPropertyChanged((obj, notifyPropertyChangedEventArgs) =>
+ {
+ SetResultDefault();
+ });
+
EnumTheorems = Enum.GetValues(typeof(EnumTheorem)).Cast<EnumTheorem>().ToList();
SelectedTheorem = EnumTheorems.First();
EdgesNum = 1;
SameVertNum = 1;
- IsTheoremCorrect = false;
- AutomorphismCount = 0;
+ PathToSave = DefaultPathToSave;
CalculateCommand = new RelayCommand(OnCalculate);
- SaveResultCommand = new RelayCommand(OnSaveResult);
+ SaveResultCommand = new RelayCommand(OnSaveResult, () => IsTheoremCorrect);
//AddItemCommand = new RelayCommand<ItemViewModel>(OnAddItem, item => Items.FirstOrDefault(e => e.Value == item.Value) == null);
//RemoveItemCommand = new RelayCommand<ItemViewModel>(OnRemoveItem, item => !item.Readonly);
//SwitchDataVisibleCommand = new RelayCommand(OnSwitchDataVisible);
//ClearSearchCommand = new RelayCommand(OnClearSearch);
+
+ EdgesNum = 3;
+ SameVertNum = 1;
+ Verticies[0].Value = 4;
+ Verticies[1].Value = 4;
+ Verticies[2].Value = 4;
}
#region Поля и свойства
+ public static MainViewModel Current { get; private set; }
+
+ private readonly string DefaultPathToSave = $"C:\\Users\\{Environment.UserName}\\Documents\\";
+ private string PathToSave { get; set; }
+
public static int MaxValue { get; } = 99;
public static int MinValue { get; } = 0;
@@ -48,6 +67,7 @@ namespace WPF.ViewModel
set
{
_selectedTheorem = value;
+ SetResultDefault();
OnPropertyChanged(() => SelectedTheorem);
}
@@ -61,6 +81,7 @@ namespace WPF.ViewModel
set
{
_edgesNum = value;
+ SetResultDefault();
OnPropertyChanged(() => EdgesNum);
UpdateVerticies();
OnPropertyChanged(() => VisibilityVerticies);
@@ -74,6 +95,7 @@ namespace WPF.ViewModel
set
{
_sameVertNum = value;
+ SetResultDefault();
OnPropertyChanged(() => SameVertNum);
UpdateVerticiesValue();
OnPropertyChanged(() => VisibilityVerticies);
@@ -132,6 +154,41 @@ namespace WPF.ViewModel
}
}
+ private TheoremAuto _result;
+ public TheoremAuto Result
+ {
+ get => _result;
+ set
+ {
+ _result = value;
+ IsTheoremCorrect = value.isSatisfyTheorem;
+ AutomorphismCount = value.CountAutomorphism;
+ OnPropertyChanged(() => Result);
+ }
+ }
+
+ private Status _status;
+ public Status Status
+ {
+ get { return _status; }
+ set
+ {
+ _status = value;
+ OnPropertyChanged(() => Status);
+ }
+ }
+
+ private string _statusMessage;
+ public string StatusMessage
+ {
+ get { return _statusMessage; }
+ set
+ {
+ _statusMessage = value;
+ OnPropertyChanged(() => StatusMessage);
+ }
+ }
+
#endregion
#region Методы и команды
@@ -151,15 +208,10 @@ namespace WPF.ViewModel
}
else if (EdgesNum < Verticies.Count)
{
- if (EdgesNum == 0)
- Verticies.Clear();
- else
+ var skip = Verticies.Skip(EdgesNum).ToList();
+ foreach (var vert in skip)
{
- var skip = Verticies.Skip(EdgesNum).ToList();
- foreach (var vert in skip)
- {
- Verticies.Remove(vert);
- }
+ Verticies.Remove(vert);
}
}
}
@@ -174,38 +226,76 @@ namespace WPF.ViewModel
}
}
-
public RelayCommand CalculateCommand { get; }
private void OnCalculate()
{
CreateGraph(EdgesNum, SameVertNum, Verticies.Select(x => x.Value).ToList());
- TheoremAuto result = default;
+ SetResultDefault();
switch (SelectedTheorem)
{
case EnumTheorem.Second:
{
- result = TheoremSecond();
+ Result = TheoremSecond();
+ Status = Status.OperationSuccess;
+ StatusMessage = "Расчет успешно выполнен";
break;
}
case EnumTheorem.Third:
{
- result = TheoremThird();
+ Result = TheoremThird();
+ Status = Status.OperationSuccess;
+ StatusMessage = "Расчет успешно выполнен";
break;
}
case EnumTheorem.Forth:
{
+ Status = Status.OperationSuccess;
+ StatusMessage = "Расчет успешно выполнен";
break;
}
}
- IsTheoremCorrect = result.isSatisfyTheorem;
- AutomorphismCount = result.CountAutomorphism;
}
public RelayCommand SaveResultCommand { get; }
private void OnSaveResult()
{
+ if (!Directory.Exists(PathToSave))
+ PathToSave = DefaultPathToSave;
+
+ var streamResult = Export(Result, SelectedTheorem);
+
+ if (streamResult.CanRead && streamResult.Length == 0)
+ {
+ Status = Status.Error;
+ StatusMessage = "Ошибка экспорта. Поток экспорта пустой.";
+ streamResult.Close();
+ return;
+ }
+ using (SaveFileDialog saveFileDialog = new SaveFileDialog()
+ {
+ Filter = "Text file (*.txt)|*.txt",/*"Text file (*.txt)|*.txt|C# file (*.cs)|*.cs",*/
+ InitialDirectory = PathToSave
+ })
+ {
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ PathToSave = Path.GetDirectoryName(saveFileDialog.FileName);
+ File.WriteAllBytes(saveFileDialog.FileName, streamResult.ToArray());
+
+ Status = Status.OperationSuccess;
+ StatusMessage = $"Файл успешно сохранен: {saveFileDialog.FileName}";
+ }
+ }
+
+ }
+
+ private void SetResultDefault()
+ {
+ Result = default;
+ Status = Status.Default;
+ StatusMessage = "Результат успешно сброшен";
}
#endregion
WPF/WPF.csproj 11(+8 -3)
diff --git a/WPF/WPF.csproj b/WPF/WPF.csproj
index ac80020..16e9ca4 100644
--- a/WPF/WPF.csproj
+++ b/WPF/WPF.csproj
@@ -36,6 +36,10 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <PropertyGroup>
+ <ApplicationIcon>
+ </ApplicationIcon>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
@@ -280,6 +284,7 @@
<Compile Include="Common\WPF\ObservableCollectionAdv.cs" />
<Compile Include="Common\WPF\RelayCommand.cs" />
<Compile Include="Model\Calculate.cs" />
+ <Compile Include="Model\ObservableCollectionExtension.cs" />
<Compile Include="Model\EnumTheorem.cs" />
<Compile Include="ViewModel\MainViewModel.cs" />
<Compile Include="View\MainWindow.xaml.cs">
@@ -320,13 +325,13 @@
<Name>HyperGraphModel</Name>
</ProjectReference>
</ItemGroup>
- <ItemGroup>
- <Folder Include="Common\Assets\" />
- </ItemGroup>
+ <ItemGroup />
<ItemGroup>
<Resource Include="FodyWeavers.xml" />
</ItemGroup>
<ItemGroup>
+ <Resource Include="Icon.ico" />
+ <Resource Include="Common\Assets\Icon.ico" />
<Content Include="Common\Microsoft.Windows.Shell.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />