using System.Windows;
namespace Notification
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
_notification.Activate();
}
}
}
using System.Windows;
using System.Windows.Controls;
namespace Notification.Controls
{
public class NotificationControl : ContentControl
{
public NotificationControl()
{
DefaultStyleKey = typeof(NotificationControl);
}
public void Activate()
{
VisualStateManager.GoToState(this, "Default", false);
VisualStateManager.GoToState(this, "Activated", true);
}
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Notification.Controls">
<KeyTime x:Key="OffsetYKeyTime">0:0:0.8</KeyTime>
<KeyTime x:Key="OpacityDelayKeyTime">0:0:1.8</KeyTime>
<KeyTime x:Key="VisibilityDelayKeyTime">0:0:2.2</KeyTime>
<Style TargetType="controls:NotificationControl">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationControl">
<Border
x:Name="RootElement"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Opacity="0"
Visibility="Collapsed">
<ContentPresenter
x:Name="ContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.RenderTransform>
<TransformGroup>
<TranslateTransform />
<RotateTransform />
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Default">
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)">
<EasingDoubleKeyFrame
KeyTime="0:0:0"
Value="0">
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="RootElement"
Storyboard.TargetProperty="Opacity">
<EasingDoubleKeyFrame
KeyTime="0:0:0"
Value="1">
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="RootElement"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Activated">
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)">
<EasingDoubleKeyFrame
KeyTime="0:0:0"
Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuadraticEase EasingMode="EaseOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame
KeyTime="{StaticResource OffsetYKeyTime}"
Value="-80">
<EasingDoubleKeyFrame.EasingFunction>
<QuadraticEase EasingMode="EaseOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="RootElement"
Storyboard.TargetProperty="Opacity">
<EasingDoubleKeyFrame
KeyTime="0:0:0"
Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame
KeyTime="{StaticResource OpacityDelayKeyTime}"
Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuadraticEase EasingMode="EaseInOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="RootElement"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="{StaticResource VisibilityDelayKeyTime}">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<Window
x:Class="Monitor.SomeWindow"
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:local="clr-namespace:Monitor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="SomeWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.Resources>
<Style
x:Key="BaseFontFamily"
TargetType="TextBlock">
<Setter Property="FontSize" Value="90" />
</Style>
<Style
x:Key="Numbers1Style"
BasedOn="{StaticResource BaseFontFamily}"
TargetType="TextBlock">
<Setter Property="Foreground" Value="LightCoral" />
</Style>
<Style
x:Key="Numbers2Style"
BasedOn="{StaticResource BaseFontFamily}"
TargetType="TextBlock">
<Setter Property="Foreground" Value="Bisque" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Style="{Binding TimeBlockStyle, RelativeSource={RelativeSource AncestorType=local:SomeWindow}}"
Text="{Binding Path=RightTeam.TeamCounter, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
<Button
Grid.Row="1"
Click="OnButtonClick" />
</Grid>
</Window>
public partial class SomeWindow : Window
{
public static readonly DependencyProperty TimeBlockStyleProperty = DependencyProperty.Register(
nameof(TimeBlockStyle), typeof(Style), typeof(SomeWindow), new PropertyMetadata(default(Style)));
public Style TimeBlockStyle
{
get { return (Style)GetValue(TimeBlockStyleProperty); }
set { SetValue(TimeBlockStyleProperty, value); }
}
public SomeWindow()
{
InitializeComponent();
TimeBlockStyle = (Style)Resources["Numbers1Style"];
}
private void OnButtonClick(object sender, RoutedEventArgs e)
{
TimeBlockStyle = (Style)Resources["Numbers2Style"];
}
}
Как организовать постоянное обновление DataGrid в отдельном потоке, чтобы при этом DataGrid был доступен, т.к. планируется добавить возможность выбирать строку из DataGrid и смотреть подробную информацию.
using System;
using System.Threading.Tasks;
namespace Tasks
{
class Program
{
static async Task Main(string[] args)
{
// Так
await Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
Console.Write("=");
}
});
// Или так (обрати внимание на Unwrap())
await Task.Factory.StartNew(async () =>
{
while (true)
{
await Task.Delay(1000);
Console.Write("=");
}
}).Unwrap();
}
}
}
<DataGrid
AutoGenerateColumns="False"
ItemsSource="{Binding Income}">
<DataGrid.Columns>
<DataGridTemplateColumn
CanUserReorder="False"
CanUserResize="False"
CanUserSort="False"
IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="viewModels:IncomeViewModel">
<Ellipse Fill="{Binding IsModified, Converter={StaticResource BooleanToBrushConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid>
using GalaSoft.MvvmLight;
namespace WpfApp.ViewModels
{
public class IncomeViewModel : ViewModelBase
{
private bool _isModified;
public bool IsModified
{
get { return _isModified; }
set { Set(ref _isModified, value); }
}
}
}
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace WpfApp.Converters
{
[ValueConversion(typeof(bool), typeof(SolidColorBrush))]
public class BooleanToBrushConverter : IValueConverter
{
public SolidColorBrush TrueBrush { get; set; } = new SolidColorBrush(Colors.Tomato);
public SolidColorBrush FalseBrush { get; set; } = new SolidColorBrush(Colors.CornflowerBlue);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? TrueBrush : FalseBrush;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
}
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MvvmLightLibsStd10" Version="5.4.1.1" />
</ItemGroup>
</Project>
<DataGrid
Grid.Row="1"
Grid.Column="1"
AutoGenerateColumns="False"
ItemsSource="{Binding Income}">
<DataGrid.Columns>
<DataGridTextColumn
Width="67"
Binding="{Binding Title}"
Header="Title" />
<DataGridTextColumn
Width="67"
Binding="{Binding Sum}"
Header="Sum" />
</DataGrid.Columns>
</DataGrid>
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight;
namespace WpfApp1.ViewModels
{
public class MainViewModel : ViewModelBase
{
public ObservableCollection<IncomeViewModel> Income { get; }
public MainViewModel()
{
Income = new ObservableCollection<IncomeViewModel>();
// Просто для теста заполняем
Income.Add(new IncomeViewModel { Title = "Зарплата", Sum = 100_000m });
}
}
/// <summary>
/// Модель представления одной строки в таблице Доход.
/// </summary>
public class IncomeViewModel : ViewModelBase
{
private string _title;
private decimal _sum;
public string Title
{
get { return _title; }
set { Set(ref _title, value); }
}
public decimal Sum
{
get { return _sum; }
set { Set(ref _sum, value); }
}
}
}
AutoGenerateColumns="False"
ItemsSource="{Binding Elements}"
<DataGrid
AutoGenerateColumns="False"
ItemsSource="{Binding Elements}">
<DataGrid.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
IsVirtualizing="True"
VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</DataGrid.ItemsPanel>
</DataGrid>
using System;
using System.Threading;
using System.Threading.Tasks;
namespace EventsInModel.Models
{
public class SearchAlgorithm
{
public string CurrentFolder { get; private set; }
public event EventHandler ProgressChanged;
public async Task Search(CancellationToken cancellationToken)
{
for (int i = 0; i < 5; i++)
{
await Task.Delay(1200, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
// Можно прогресс передавать и в качестве аргумента события,
// но в данном случае, вряд ли это оправдано. Обработав событие можно получить
// доступ к отправителю события и прочитать его свойства.
CurrentFolder = i.ToString();
ProgressChanged?.Invoke(this, EventArgs.Empty);
}
}
}
}
using System;
using System.Threading;
using System.Windows.Input;
using EventsInModel.Models;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
namespace EventsInModel.ViewModels
{
// ViewModelBase из библиотеки MvvmLight
public class MainViewModel : ViewModelBase
{
//private readonly object _sync = new object();
private readonly SearchAlgorithm _search;
private string _currentFolder;
// Логику с отменой можно вынести в отдельный класс, чтобы не писать простыню
// с отменой в каждом таком месте с операцией, которая может быть отменена, а
// в UI приложениях такое сплошь и рядом.
private volatile CancellationTokenSource _lastCancellationTokenSource;
public string CurrentFolder
{
get { return _currentFolder; }
private set { Set(ref _currentFolder, value); }
}
public ICommand SearchCommand { get; }
public MainViewModel(SearchAlgorithm search)
{
_search = search;
_search.ProgressChanged += OnSearchProgressChanged;
SearchCommand = new RelayCommand(Search);
}
public override void Cleanup()
{
//lock (_sync)
{
_lastCancellationTokenSource?.Cancel();
}
_search.ProgressChanged -= OnSearchProgressChanged;
base.Cleanup();
}
/// <summary>
/// Прерывает прошлый поиск и запускает новый.
/// </summary>
private async void Search()
{
CancellationTokenSource currentTokenSource;
// В случае, если такой метод вызывать не из UI потока, то lock здесь нужен
// Если использовать только из UI потока как здесь, то lock можно удалить.
// Ещё бы я вынес логику в отдельный класс и использовал в других проектах в том числе.
//lock (_sync)
{
_lastCancellationTokenSource?.Cancel();
currentTokenSource = new CancellationTokenSource();
_lastCancellationTokenSource = currentTokenSource;
}
try
{
await _search.Search(currentTokenSource.Token);
}
catch (OperationCanceledException)
{
// Ignored.
}
finally
{
//lock (_sync)
{
currentTokenSource.Dispose();
if (ReferenceEquals(_lastCancellationTokenSource, currentTokenSource))
{
_lastCancellationTokenSource = null;
}
}
}
}
private void OnSearchProgressChanged(object sender, EventArgs e)
{
var search = (SearchAlgorithm)sender;
CurrentFolder = search.CurrentFolder;
}
}
}
using System.Windows;
using EventsInModel.Models;
using EventsInModel.ViewModels;
namespace EventsInModel
{
public partial class MainWindow : Window
{
private readonly MainViewModel _viewModel;
public MainWindow()
{
InitializeComponent();
_viewModel = new MainViewModel(new SearchAlgorithm());
DataContext = _viewModel;
Loaded += OnLoaded;
Closing += OnClosing;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
_viewModel.SearchCommand.Execute(null);
_viewModel.SearchCommand.Execute(null);
}
private void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
_viewModel.Cleanup();
}
}
}
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MvvmLightLibsStd10" Version="5.4.1.1" />
</ItemGroup>
</Project>
<ControlTemplate
x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey,
TypeInTargetAssembly={x:Type MenuItem}}">
<!-- Много кода -->
</ControlTemplate>
<ContentPresenter
x:Name="Icon"
Width="16"
Height="16"
Margin="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ContentSource="Icon"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Rectangle
Width="1"
Margin="29,2,0,2"
HorizontalAlignment="Left"
Fill="{StaticResource Menu.Static.Separator}" />
<Menu
Grid.Row="0"
Height="25"
VerticalAlignment="Top"
DockPanel.Dock="Top">
<MenuItem Style="{StaticResource MenuItemStyle}" Header="Тесты">
<MenuItem
Icon="101"
Command="{Binding WorkspaceViewModel.UpdateTestsCommand}"
Header="Обновить список тестов"
IsEnabled="{Binding Mode, Converter={StaticResource ApplicationModeEnumToBooleanConverter}, ConverterParameter='Tests'}" />
<!-- -->
</MenuItem>
<MenuItem Header="Режим">
<!-- -->
</MenuItem>
</Menu>
<Window
x:Class="WpfDataGrid.Views.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:system="clr-namespace:System;assembly=mscorlib"
xmlns:viewModels="clr-namespace:WpfDataGrid.ViewModels"
Title="MainWindow"
Width="800"
Height="450"
DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Window.Resources>
<SolidColorBrush
x:Key="BackgroundOfSelectedDataGridRow"
Color="#B6B6B6" />
<SolidColorBrush
x:Key="BorderBrushOfSelectedDataGridRow"
Color="#FF2485C9" />
<SolidColorBrush
x:Key="ForegroundOfSeletedDataGridRow"
Color="Black" />
<SolidColorBrush
x:Key="GridLinesBrush"
Color="#FFB0B0B0" />
<FontFamily x:Key="DefaultFontFamylyKey">
Microsoft Sans Serif
</FontFamily>
<Style
x:Key="DefaultDataGridCellStyle"
TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#B2FFD0A2" />
<Setter Property="BorderBrush" Value="#99FFE5CC" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
<Style
x:Key="DataGridStyle"
TargetType="{x:Type DataGrid}">
<Setter Property="RowBackground" Value="#FFE6E6E6" />
<Setter Property="AlternatingRowBackground" Value="#FFF1F1F1" />
<Setter Property="AlternationCount" Value="2" />
<Setter Property="HorizontalGridLinesBrush" Value="{StaticResource GridLinesBrush}" />
<Setter Property="VerticalGridLinesBrush" Value="{StaticResource GridLinesBrush}" />
<Setter Property="FontFamily" Value="{StaticResource DefaultFontFamylyKey}" />
<Setter Property="FontSize" Value="15" />
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="RowStyle">
<Setter.Value>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource BackgroundOfSelectedDataGridRow}" />
<Setter Property="BorderBrush" Value="{StaticResource BorderBrushOfSelectedDataGridRow}" />
<Setter Property="Foreground" Value="{StaticResource ForegroundOfSeletedDataGridRow}" />
<Setter Property="Tag" Value="{Binding}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#B2FFD0A2" />
<Setter Property="BorderBrush" Value="#99FFE5CC" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
<Setter Property="CellStyle" Value="{StaticResource DefaultDataGridCellStyle}" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DataGrid
Margin="10,10,10,0"
AutoGenerateColumns="False"
ItemsSource="{Binding Collection}"
Style="{StaticResource DataGridStyle}">
<DataGrid.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
IsVirtualizing="True"
VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</DataGrid.ItemsPanel>
<DataGrid.Columns>
<DataGridTemplateColumn
x:Name="PropertiesUpdateIndicatorColumn"
CanUserReorder="False"
CanUserResize="False"
CanUserSort="False"
IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="viewModels:ItemViewModel">
<Rectangle Fill="{Binding IsChecked, Converter={StaticResource BooleanToBrushConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate DataType="viewModels:ItemViewModel">
<TextBlock Text="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
Width="50"
ClipboardContentBinding="{x:Null}"
Header="Выбран">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="viewModels:ItemViewModel">
<CheckBox
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.HeaderTemplate>
<ItemContainerTemplate>
<TextBlock
Text=""
ToolTip="{Binding Path=Text, RelativeSource={RelativeSource Self}}"
ToolTipService.HasDropShadow="False"
ToolTipService.Placement="Relative">
<TextBlock.Resources>
<Style TargetType="ToolTip">
<Setter Property="VerticalOffset" Value="-1" />
<Setter Property="HorizontalOffset" Value="-1" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="HasDropShadow" Value="False" />
</Style>
</TextBlock.Resources>
</TextBlock>
</ItemContainerTemplate>
</DataGridTemplateColumn.HeaderTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
x:Name="TitleColumn"
ClipboardContentBinding="{x:Null}"
Header="Название"
SortMemberPath="Title">
<DataGridTemplateColumn.HeaderTemplate>
<ItemContainerTemplate>
<TextBlock
Text="Название"
ToolTip="{Binding Path=Text, RelativeSource={RelativeSource Self}}"
ToolTipService.HasDropShadow="False"
ToolTipService.Placement="Relative">
<TextBlock.Resources>
<Style TargetType="ToolTip">
<Setter Property="VerticalOffset" Value="-1" />
<Setter Property="HorizontalOffset" Value="-1" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="HasDropShadow" Value="False" />
</Style>
</TextBlock.Resources>
</TextBlock>
</ItemContainerTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title, Mode=OneWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox
MaxLength="120"
Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button
Grid.Row="1"
Width="75"
Margin="10,6,0,10"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="OnDeleteButtonClick"
Content="Delete" />
</Grid>
</Window>
<Window
x:Class="WpfVectorImage.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:icons="clr-namespace:WpfVectorImage.Icons"
xmlns:local="clr-namespace:WpfVectorImage"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Grid>
<icons:DumbbellIcon />
</Grid>
</Window>
<UserControl
x:Class="WpfVectorImage.Icons.DumbbellIcon"
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:local="clr-namespace:WpfVectorImage.Icons"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Viewbox Stretch="Uniform">
<Canvas
Name="Layer_1"
Width="512"
Height="512">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0" />
</Canvas.RenderTransform>
<Canvas.Resources />
<Canvas Name="g79">
<Canvas Name="g73">
</Canvas>
</Canvas>
</Canvas>
</Viewbox>
</UserControl>
int i = CarNumber.Length; // Я уже переименовал и свойства
int v = CarMark.Length;
if (i <= 0)
{
dataProperty = $"Данной машины не найдено на парковке";
dataPlace = $"Повторите попытку";
}
$"Данной машины не найдено на парковке";
namespace PageNavigation.Services
{
public interface INavigationService
{
void NavigateToPage1();
void NavigateToPage2();
}
}
using System.Windows.Controls;
using PageNavigation.Pages;
namespace PageNavigation.Services
{
public class NavigationService : INavigationService
{
private readonly Frame _frame;
public NavigationService(Frame frame)
{
_frame = frame;
}
public void NavigateToPage1()
{
_frame.Navigate(new Page1());
}
public void NavigateToPage2()
{
_frame.Navigate(new Page2());
}
}
}
using System.Windows.Controls;
namespace PageNavigation.Services
{
public static class Ioc
{
public static INavigationService NavigationService { get; private set; }
public static void Init(Frame frame)
{
NavigationService = new NavigationService(frame);
}
}
}
using System.Windows.Controls;
using Autofac;
namespace PageNavigation.Services
{
public static class Ioc
{
private static IContainer _container;
public static INavigationService NavigationService
{
get { return _container.Resolve<INavigationService>(); }
}
//public static MainViewModel MainViewModel
//{
// get { return _container.Resolve<MainViewModel>(); }
//}
public static void Init(Frame frame)
{
var builder = new ContainerBuilder();
builder.RegisterType<NavigationService>()
.As<INavigationService>()
.SingleInstance()
.WithParameter(new TypedParameter(typeof(Frame), frame));
//builder.RegisterType<MainViewModel>()
// .SingleInstance();
_container = builder.Build();
}
}
}
<Window
x:Class="PageNavigation.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"
Title="MainWindow"
Width="525"
Height="350"
Loaded="OnLoaded"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="266*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Frame x:Name="_frame" />
<StackPanel
Grid.Row="1"
Margin="8,0,0,6"
Orientation="Horizontal">
<Button
MinWidth="75"
MinHeight="29"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="OnNavigateToPage1ButtonClick"
Content="Page1" />
<Button
MinWidth="75"
MinHeight="29"
Margin="8,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="OnNavigateToPage2ButtonClick"
Content="Page2" />
</StackPanel>
</Grid>
</Window>
using System.Windows;
using PageNavigation.Services;
namespace PageNavigation
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Ioc.Init(_frame);
}
private void OnNavigateToPage1ButtonClick(object sender, RoutedEventArgs e)
{
Ioc.NavigationService.NavigateToPage1();
}
private void OnNavigateToPage2ButtonClick(object sender, RoutedEventArgs e)
{
Ioc.NavigationService.NavigateToPage2();
}
}
}
<Page
x:Class="PageNavigation.Pages.Page1"
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"
Title="Page1"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid>
<TextBlock Margin="5">
Это Page 1
</TextBlock>
<Button
Padding="12,3,12,3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Click="OnNavigateToAnotherPageButtonClick"
Content="Перейти на Page 2" />
</Grid>
</Page>
using System.Windows.Controls;
using PageNavigation.Services;
namespace PageNavigation.Pages
{
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
private void OnNavigateToAnotherPageButtonClick(object sender, System.Windows.RoutedEventArgs e)
{
Ioc.NavigationService.NavigateToPage2();
}
}
}
<Page
x:Class="PageNavigation.Pages.Page2"
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"
Title="Page2"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid>
<TextBlock Margin="5">
Это Page 2
</TextBlock>
<Button
Padding="12,3,12,3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Click="OnNavigateToAnotherPageButtonClick"
Content="Перейти на Page 1" />
</Grid>
</Page>
using System.Windows;
using System.Windows.Controls;
using PageNavigation.Services;
namespace PageNavigation.Pages
{
public partial class Page2 : Page
{
public Page2()
{
InitializeComponent();
}
private void OnNavigateToAnotherPageButtonClick(object sender, RoutedEventArgs e)
{
Ioc.NavigationService.NavigateToPage1();
}
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ProgressBarExample
{
internal class Analyzer
{
private readonly SynchronizationContext _synchronizationContext;
public Analyzer()
{
// Если экземпляр класса будет создан в UI потоке,
// то здесь будет контекст синхронизации UI потока, иначе пула потоков
_synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
}
public event EventHandler<AnalyzerEventArgs> ProgressChanged;
public async Task<Data> LoadDataInDB()
{
var result = await Task.Run(async () =>
{
for (int i = 0; i < 100; i++)
{
await Task.Delay(250);
OnProgressChanged(new AnalyzerEventArgs("line " + (i + 1), 100));
}
return new Data() { Text = "Данные " };
});
return result;
}
private void OnProgressChanged(AnalyzerEventArgs args)
{
// Перенаправляем выполнение в UI поток не ожидая пока отработает метод обработчик события.
_synchronizationContext.Post(state =>
{
ProgressChanged?.Invoke(this, (AnalyzerEventArgs)state);
}, args); // args передаётся в переменную state (грубо говоря)
}
}
}
namespace ProgressBarExample
{
public class AnalyzerEventArgs
{
public int MaxLines { get; }
public string CurrentLine { get; }
public AnalyzerEventArgs(string currentLine, int maxLines)
{
CurrentLine = currentLine;
MaxLines = maxLines;
}
}
}
namespace ProgressBarExample
{
public class Data
{
public string Text { get; set; }
}
}
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
namespace ProgressBarExample
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
private readonly Analyzer _analyzer;
private readonly Style _normalBarStyle;
private readonly Style _loadBarStyle;
private readonly Style _errorBarStyle;
private string _maxLines;
private string _currentLine;
public string MaxLines
{
get { return _maxLines; }
set
{
_maxLines = value;
OnPropertyChanged();
}
}
public string CurrentLine
{
get { return _currentLine; }
set
{
_currentLine = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
InitializeComponent();
_normalBarStyle = FindResource("NormalStatusBar") as Style;
_loadBarStyle = FindResource("LoadDataStatusBar") as Style;
_errorBarStyle = FindResource("ErrorStatusBar") as Style;
_statusBar.Style = _normalBarStyle;
_analyzer = new Analyzer();
_analyzer.ProgressChanged += OnAnalyzerProgressChanged;
}
private void OnAnalyzerProgressChanged(object sender, AnalyzerEventArgs args)
{
// Передавать каждый раз одно и тоже бессмысленно, сделаете сами как нужно
MaxLines = args.MaxLines.ToString();
CurrentLine = args.CurrentLine;
}
private async void LoadDataToDB_Click(object sender, RoutedEventArgs e)
{
_statusBar.Style = _loadBarStyle;
Mouse.OverrideCursor = Cursors.Wait;
try
{
var data = await _analyzer.LoadDataInDB();
MessageBox.Show(data.Text);
}
finally
{
Mouse.OverrideCursor = Cursors.Arrow;
_statusBar.Style = _normalBarStyle;
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
<Window
x:Class="ProgressBarExample.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:local="clr-namespace:ProgressBarExample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
<Window.Resources>
<Style x:Key="NormalStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#FF007ACC" />
</Style>
<Style x:Key="LoadDataStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#9333FF" />
</Style>
<Style x:Key="ErrorStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#eb4034" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Menu VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem
x:Name="LoadDataToDB"
Click="LoadDataToDB_Click"
Header="LoadDataToDB" />
</MenuItem>
</Menu>
<DockPanel
x:Name="_statusBar"
Grid.Row="1"
Style="{StaticResource LoadDataStatusBar}">
<!-- Style меняться во время выполнения LoadDataInDB() -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="10,0,0,0"
Foreground="White"
Text="Статус данных" />
<DockPanel Grid.Column="1" HorizontalAlignment="Right">
<TextBlock
Margin="0,0,5,0"
Foreground="White"
Text="{Binding CurrentLine}" />
<!-- должно меняться во время выполнения LoadDataInDB() -->
<TextBlock
Margin="0,0,5,0"
Foreground="White"
Text="/" />
<TextBlock
Margin="0,0,10,0"
Foreground="White"
Text="{Binding MaxLines}" />
</DockPanel>
</Grid>
</DockPanel>
</Grid>
</Window>
<Window x:Class="Wpf_Task.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<Storyboard x:Key="OnLoaded1"
RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="border"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<EasingDoubleKeyFrame KeyTime="0"
Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:1"
Value="360" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource OnLoaded1}" />
</EventTrigger>
</Window.Triggers>
<Grid>
<Button x:Name="executeButton"
Width="75"
Margin="0,216,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Click="Button_Click"
Content="Выполнить"
TextOptions.TextFormattingMode="Display" />
<Rectangle x:Name="border"
Width="100"
Height="100"
Margin="208,57,208,161"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RenderTransformOrigin="0.5,0.5">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFD1BD69" />
<GradientStop Offset="1" Color="#FFFFF5C9" />
</LinearGradientBrush>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<TextBlock x:Name="_result"
Margin="0,187,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Text="..."
TextOptions.TextFormattingMode="Display"
TextWrapping="Wrap" />
</Grid>
</Window>
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace Wpf_Task
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
executeButton.IsEnabled = false;
Task<int>.Factory.StartNew(() =>
{
return Auth.Login();
})
.ContinueWith(task => //Выполнить код в основном потоке (TaskScheduler.FromCurrentSynchronizationContext())
{
executeButton.IsEnabled = true;
_result.Text = task.Result.ToString();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
}
public static class Auth
{
private static int _counter;
public static int Login()
{
Thread.Sleep(1000);
return ++_counter;
}
}
}
public MainViewModel Main
{
get
{
return !ViewModelBase.IsInDesignModeStatic ?
_container.Resolve<MainViewModel>() :
_designerMainVm ?? (_designerMainVm =
new MainViewModel(null, null, null, null) { Settings = new AppSettings() });
}
}
public class ViewModelLocator : ViewModelLocatorBase
{
private readonly IContainer _container;
private static ViewModelLocator _locator;
public ViewModelLocator()
{
_locator = this;
if (!ViewModelBase.IsInDesignModeStatic)
{
Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
Application.Current.MainWindow.Loaded += MainWindow_Loaded;
Application.Current.MainWindow.Closing += MainWindow_Closing;
}
LogManager.Logger.LogPath = LocalConfiguration.Instance.Folders.Logs;
DispatcherHelper.Initialize();
CorrelationsLocator.Initialize();
if (!ViewModelBase.IsInDesignModeStatic)
{
ProgramIdentification.Initialize(ProgramIdentifier.CbpOperator);
LocalConfiguration.Instance.Folders.CheckFolders();
LocalConfiguration.Instance.LoadAppConfig();
LocalConfiguration.Instance.LoadLocalSettings();
WpfSingleInstance.AppIsAlreadyRunning += (sender, args) =>
MessageBox.Show(string.Format("Приложение: {0} уже запущено", args.AppName));
WpfSingleInstance.Make();
}
_container = RegisterDependencies(LocalConfiguration.Instance);
}
private IContainer RegisterDependencies(LocalConfiguration config)
{
var builder = new ContainerBuilder();
builder.RegisterType<LauncherViewModel>().SingleInstance();
builder.RegisterType<ShutdownViewModel>().SingleInstance();
builder.RegisterType<CommandManager>().SingleInstance();
builder.RegisterType<AccountControllerVm>().SingleInstance();
builder.RegisterType<ComponentEditorViewModel>().SingleInstance();
builder.RegisterType<ComponentSelectorViewModel>().SingleInstance();
builder.RegisterType<RecipeTimeSetEditorViewModel>().SingleInstance();
builder.RegisterType<CategoryEditorViewModel>().SingleInstance();
builder.RegisterType<AboutDialogViewModel>().SingleInstance();
builder.RegisterType<L1ApplicationManagerViewModel>().SingleInstance();
builder.RegisterType<CarEditorViewModel>() //Редактор машин
.OnActivated(e =>
{
e.Instance.WindowSettings = config.Settings.CarsWindowSettings; //Настройки окна (положение, размер, состояние)
}).SingleInstance();
builder.RegisterType<ClientsEditorViewModel>() //Редактор клиентов
.OnActivated(e =>
{
e.Instance.WindowSettings = config.Settings.ClientsWindowSettings; //Настройки окна (положение, размер, состояние)
}).SingleInstance();
builder.RegisterType<ReportsWindowViewModel>() //Отчёты
.OnActivated(e =>
{
e.Instance.WindowSettings = config.Settings.ReportsWindowSettings; //Настройки окна (положение, размер, состояние)
e.Instance.ReportsFolder = config.Folders.Documents;
e.Instance.ReportMode = ReportMode.Applications;
});
builder.RegisterType<EventLogViewModel>() //Журнал событий
.OnActivated(e =>
{
e.Instance.WindowSettings = config.Settings.EventLogWindowSettings; //Настройки окна (положение, размер, состояние)
e.Instance.SetConfiguration(config.Config, config.Folders.EventReportFolder);
});
builder.RegisterType<RecipesEditorViewModel>() //Редактор рецептов
.OnActivated(e =>
{
e.Instance.WindowSettings = config.Settings.RecipeWindowSettings; //Настройки окна (положение, размер, состояние)
e.Instance.SetEditorSettings(config.Settings.RecipeEditorConfig);
})
.SingleInstance();
builder.RegisterType<ApplicationsEditorViewModel>() //Редактор заявок
.OnActivated(e =>
{
e.Instance.LastSelectedItems = config.Settings.LastSelectedItemsInAppWindow; //Состояние последних выбранных элементов.
e.Instance.WindowSettings = config.Settings.AppEditorWindowSettings;
})
.SingleInstance();
builder.RegisterType<MainViewModel>()
.OnActivated(e =>
{
var appManager = e.Context.Resolve<L1ApplicationManagerViewModel>();
appManager.Main = e.Instance;
if (!ViewModelBase.IsInDesignModeStatic)
{
e.Instance.Title = ProgramIdentification.GetCurrentProgramName();
}
e.Instance.Settings = config.Settings.ApplicationSettings;
})
.SingleInstance();
return builder.Build();
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
WindowManager.Instance.Initialize(Application.Current.MainWindow, Main);
Main.OnWindowLoaded();
}
private void MainWindow_Closing(object sender, CancelEventArgs e)
{
Debug.WriteLine("Начало: MainWindow_Closing");
Window window = (Window)sender;
Debug.WriteLine("Конец: MainWindow_Closing");
if (WindowManager.Instance.OpenMessageDialog(DialogIcons.Help, DialogButtons.YesNo,
"Выход из программы",
"Вы действительно хотите завершить работу приложения?") == UserDialogResult.No)
e.Cancel = true;
else
{
window.Closing -= MainWindow_Closing;
try
{
LocalConfiguration.Instance.SaveLocalSettings();
LocalConfiguration.Instance.SaveCurrentAppConfig();
}
catch (Exception ex)
{
LogManager.Logger.AppendException(ex);
}
}
}
private void Current_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
LogManager.Logger.AppendException(e.Exception);
MessageBox.Show(e.Exception.ToString());
}
#region Свойства
public static ViewModelLocator Current
{
get { return _locator; }
}
public MainViewModel Main
{
get { return _container.Resolve<MainViewModel>(); }
}
public L1ApplicationManagerViewModel ApplicationsManager
{
get { return _container.Resolve<L1ApplicationManagerViewModel>(); }
}
public AccountControllerVm AccountController
{
get { return _container.Resolve<AccountControllerVm>(); }
}
public ShutdownViewModel Shutdown
{
get { return _container.Resolve<ShutdownViewModel>(); }
}
public CategoryEditorViewModel CategoryEditor
{
get { return _container.Resolve<CategoryEditorViewModel>(); }
}
public ApplicationsEditorViewModel ApplicationsEditor
{
get { return _container.Resolve<ApplicationsEditorViewModel>(); }
}
public RecipesEditorViewModel RecipesEditor
{
get { return _container.Resolve<RecipesEditorViewModel>(); }
}
public ComponentEditorViewModel ComponentEditor
{
get { return _container.Resolve<ComponentEditorViewModel>(); }
}
public ComponentSelectorViewModel ComponentsSelector
{
get { return _container.Resolve<ComponentSelectorViewModel>(); }
}
/// <summary>Редактор клиентов</summary>
public ClientsEditorViewModel ClientsEditor
{
get { return _container.Resolve<ClientsEditorViewModel>(); }
}
public CarEditorViewModel CarsEditor
{
get { return _container.Resolve<CarEditorViewModel>(); }
}
public CommandManager CommonCommands
{
get { return _container.Resolve<CommandManager>(); }
}
public LauncherViewModel Launcher
{
get { return _container.Resolve<LauncherViewModel>(); }
}
public AboutDialogViewModel About
{
get { return _container.Resolve<AboutDialogViewModel>(); }
}
/// <summary>
/// Возвращает новый экземпляр модели представления Отчётов
/// </summary>
public ReportsWindowViewModel NewReport
{
get { return _container.Resolve<ReportsWindowViewModel>(); }
}
/// <summary>
/// Возвращает новый экземпляр модели представления Журнала событий
/// </summary>
public EventLogViewModel NewEventLog
{
get { return _container.Resolve<EventLogViewModel>(); }
}
#endregion
#region Методы
#endregion
}