SELECT * FROM testimony WHERE Name IN(@record1, @record2)
string sql = "SELECT * FROM testimony WHERE Name IN({0})";
string parameters = "";
string[] array = new string[] { "Запись 1", "Запись 2" };
for (int i = 0; i < array.Length; i++)
{
parameters += "@record" + (i + 1) + (i < array.Length - 1 ? ", ": "");
}
using (SqlCommand cmd = new SqlCommand(string.Format(sql, parameters), this.connect))
{
// Добавить параметры
for (int i = 0; i < array.Length; i++)
{
cmd.Parameters.AddWithValue("@record" + (i + 1), array[i]);
}
cmd.ExecuteNonQuery();
}
<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>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>
using System;
using System.Threading;
using System.Threading.Tasks;
namespace HttpClientExample
{
class Program
{
// В качестве исключения я расположил в самом верху класса метод Main,
// обычно здесь должны быть поля класса, а все методы ниже.
#region Entry point
static async Task Main(string[] args)
{
var program = new Program();
await program.Run(args);
}
#endregion
private readonly SomeClient _client;
public Program()
{
_client = new SomeClient("http://localhost:5000");
}
private async Task Run(string[] args)
{
bool success = false;
do
{
try
{
// CancellationToken пригодится в приложениях с UI, где нужно, например,
// закрыть окно или уйти со страницы не дожидаясь, пока запрос отработает.
// Здесь заранее это заложено, можно и не использовать, если приложение консольное.
string data = await _client.GetData(CancellationToken.None);
success = true;
Console.WriteLine(data);
}
catch (ApiException ex)
{
// Одна реакция
Console.WriteLine(ex);
Console.WriteLine();
}
catch (Exception ex)
{
// Другая реакция
Console.WriteLine(ex);
Console.WriteLine();
}
await Task.Delay(150);
} while (!success);
_client.Dispose();
}
}
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace HttpClientExample
{
public class SomeClient : IDisposable
{
private const string GET_TEXT_PART = "/api/system/get-text";
private const string GET_USER_PART = "/api/system/get-user";
private HttpClient _httpClient;
public Dictionary<string, string> DefaultHeaders { get; }
public SomeClient(string baseAddress)
{
var httpHandler = new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
_httpClient = new HttpClient(httpHandler)
{
BaseAddress = new Uri(baseAddress)
};
DefaultHeaders = new Dictionary<string, string>
{
["Accept"] = "*/*",
["Accept-Encoding"] = "gzip, deflate",
["Cache-Control"] = "no-cache",
["Connection"] = "keep-alive",
};
}
public void Dispose()
{
if (_httpClient != null)
{
_httpClient.Dispose();
_httpClient = null;
GC.SuppressFinalize(this);
}
}
public async Task<string> GetData(CancellationToken cancellationToken)
{
string text = await InvokeText(HttpMethod.Get, GET_TEXT_PART, cancellationToken);
// Возможно, что-то залогировал.
return text;
}
public async Task<User> GetUser(CancellationToken cancellationToken)
{
var user = await InvokeJson<User>(HttpMethod.Get, GET_USER_PART, cancellationToken);
// Возможно, что-то залогировал.
return user;
}
/// <summary>
/// Sets the request.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="requestContent">Content of the request.</param>
private void SetRequest(HttpRequestMessage request, object requestContent)
{
foreach (var header in DefaultHeaders)
{
request.Headers.Add(header.Key, header.Value);
}
if (requestContent != null)
{
request.Content = new StringContent(JsonConvert.SerializeObject(requestContent),
Encoding.UTF8,
Constants.HttpMimeTypes.JsonContentType);
}
}
/// <summary>
/// Invokes the specified HTTP method.
/// </summary>
/// <param name="httpMethod">The HTTP method.</param>
/// <param name="relativeUrl">The relative URL.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <param name="requestContent">Content of the request.</param>
/// <returns>instance of the type T</returns>
/// <exception cref="ApiException"></exception>
private async Task<string> InvokeText(HttpMethod httpMethod, string relativeUrl, CancellationToken cancellationToken, object requestContent = null)
{
using (var request = new HttpRequestMessage(httpMethod, relativeUrl))
{
SetRequest(request, requestContent);
using (HttpResponseMessage response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead, cancellationToken))
{
string responseText = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return responseText;
}
throw new ApiException(response.StatusCode, responseText);
}
}
}
/// <summary>
/// Invokes the specified HTTP method.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="httpMethod">The HTTP method.</param>
/// <param name="relativeUrl">The relative URL.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <param name="requestContent">Content of the request.</param>
/// <returns>instance of the type T</returns>
/// <exception cref="ApiException"></exception>
private async Task<T> InvokeJson<T>(HttpMethod httpMethod, string relativeUrl, CancellationToken cancellationToken, object requestContent = null)
{
using (var request = new HttpRequestMessage(httpMethod, relativeUrl))
{
SetRequest(request, requestContent);
using (HttpResponseMessage response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead, cancellationToken))
{
string responseText = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var resource = JsonConvert.DeserializeObject<T>(responseText);
return resource;
}
throw new ApiException(response.StatusCode, responseText);
}
}
}
private static class Constants
{
public static class HttpMimeTypes
{
/// <summary>
/// The json content type
/// </summary>
public const string JsonContentType = "application/json";
}
}
}
}
using Newtonsoft.Json;
namespace HttpClientExample
{
public class User
{
[JsonProperty("id", Required = Required.Always)]
public long Id { get; set; }
[JsonProperty("name", Required = Required.Always)]
public string Name { get; set; }
}
}
Run Anywhere
MimeKit and MailKit support Windows, Linux, Mac, iOS, Android, Windows Phone and more!
await Task.Delay(250);
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 Task<Data> DoWork()
{
return Task.Run(async () =>
{
for (int i = 0; i < 100; i++)
{
// Имитация долгой работы
await Task.Delay(250);
// Здесь ты можешь так же как в своём коде вызывать OnProgressChanged
// раз в несколько миллисекунд. В форме в UI потоке без Invoke обрабатывать
// событие, выводя те данные, которые ты поместишь в AnalyzerEventArgs
OnProgressChanged(new AnalyzerEventArgs("line " + (i + 1), 100));
}
return new Data() { Text = "Данные " };
});
}
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; }
}
}
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.IO;
namespace InputOutputExample
{
class Program
{
static void Main(string[] args)
{
string inputFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "input.txt");
string outputFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "output.txt");
using var input = new StreamReader(File.OpenRead(inputFile));
Console.SetIn(input);
using var output = new StreamWriter(File.OpenWrite(outputFile));
Console.SetOut(output);
string line = null;
while ((line = Console.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
}
Далее основной поток вызывает определенный в библиотеке MSCorEE.dll метод, который инициализирует CLR, загружает сборку EXE, а затем вызывает ее метод Main, в котором содержится точка входа. На этом процедура запуска управляемого приложения считается завершенной.