Скирншот экрана WPF

var topLeftCorner = this.PointToScreen(new System.Windows.Point(0, 0));
var topLeftGdiPoint = new System.Drawing.Point((int)topLeftCorner.X, (int)topLeftCorner.Y);
var size = new System.Drawing.Size((int)this.ActualWidth, (int)this.ActualHeight);
var screenShot = new Bitmap((int)this.ActualWidth, (int)this.ActualHeight);
using (var graphics = Graphics.FromImage(screenShot))
{
graphics.CopyFromScreen(topLeftGdiPoint, new System.Drawing.Point(),
size, CopyPixelOperation.SourceCopy);
}
screenShot.Save(@"screenshot.png", ImageFormat.Png);

Как сделать скриншот с WPF контрола

public void SaveImage(Visual visual, string filePath)
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(visual);
RenderTargetBitmap bitmap = new RenderTargetBitmap((Int32)bounds.Width, (Int32)bounds.Height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(visual);
PngBitmapEncoder image = new PngBitmapEncoder();
image.Frames.Add(BitmapFrame.Create(bitmap));
using (Stream fs = File.Create(filePath))
{
image.Save(fs);
}
}

А загрузить изображение в Image можно вот так:

ImageSourceConverter conv = new ImageSourceConverter();
ImageSource imageSource = (ImageSource)conv.ConvertFromString(name);
image.Source = imageSource;

Динамическая компиляция и в выполнение кода C#

//выполнение 
private string EvalCode(string typeName, string methodName, string sourceCode)
{
string output = ":)";
var compiler = CodeDomProvider.CreateProvider("CSharp");
var parameters = new CompilerParameters
{
CompilerOptions = "/t:library",
GenerateInMemory = true,
IncludeDebugInformation = true,
};

foreach (var reference in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
parameters.ReferencedAssemblies.Add(reference.Location);
}
catch (Exception ex)
{
//Debug.WriteLine("Cannot add assembly " + reference.FullName + " as reference.");
}
}
//если надо
parameters.ReferencedAssemblies.Add(Application.StartupPath + "\\Some.dll");

var results = compiler.CompileAssemblyFromSource(parameters, sourceCode);

if (!results.Errors.HasErrors)
{
var assembly = results.CompiledAssembly;
var evaluatorType = assembly.GetType(typeName);
var evaluator = Activator.CreateInstance(evaluatorType);

output = (string)InvokeMethod(evaluatorType, methodName, evaluator, new object[] { output });
return output;
}

output = "\r\Что-то пошло не так!";
return results.Errors.Cast<CompilerError>().Aggregate(output, (current, ce) => current + string.Format("\r\nline {0}: {1}", ce.Line, ce.ErrorText));
}
//[FileIOPermission(SecurityAction.Deny, Unrestricted = true)]
private object InvokeMethod(Type evaluatorType, string methodName, object evaluator, object[] methodParams)
{
try
{
return evaluatorType.InvokeMember(methodName, System.Reflection.BindingFlags.InvokeMethod, null, evaluator, methodParams);
}
catch
{
return null;
}
}

WCF Data Services 5.0 ошибка System.Data.Services.Providers.ResourceType

Если вы делаете ODate сервисы версии 5.0 то скорее всего столкнетесь с проблемой 'System.Data.Services.Providers.ResourceType' threw an exception.'

для того чтобы это исправить нужно добавить в  Reference проекта следующие библиотеки:

Microsoft.Data.Edm.dll
Microsoft.Data.OData.dll
System.Spatial.dll

также возможно понадобиться:

Microsoft.Data.Services.dll
Microsoft.Data.Services.Client.dll

Если вы используете OpenAccess ORM то в проекте должны быть следующие библиотеки, которые должны копироваться локально:

Обязательные:
Telerik.OpenAccess.dll
Telerik.OpenAccess.35.Extensions.dll
Telerik.OpenAccess.Runtime.dll

для OData:
Telerik.OpenAccess.DataServices.50.dll

Вообще для просмотра зависимостей лучше всего использовать Telerik JustDecompile http://www.telerik.com/products/decompiler.aspx

 

Как работать с DateTime в C#

Как мы знаем тип DateTime хранит время и дату, по этому этот класс достаточно спечифично выглядит для математических операций типа получения разницы в минутах. Или добавление или вычитания времени.
1. Добавление времени:
Тут все просто DateTime.Add (AddDays, AddHours, AddMonths и т.п.) и все что с ним связано, так можно добавлять к времени дни, часы, минуты и прочее.  Если нужно вычесть то добавляйте со знаком минус.

2. Математические операции:

Для этого нам нужен прекрасный класс TimeSpan.
Например, нам нужно узнать разницу между двумя DateTime в минутах
Для этого нужно сделать:

var time = (time1 – time2);
double rez = time.TotalMinutes();

Смысл в том что операции над DateTime возвращают TimeSpan, у которого есть свойства Total* – вот там и храниться общее время в выбранных единицах.

В свойстве Minutes в данном случае будут просто текущее количество минут (скажем для 1 час, 22 минуты – там будет храниться 22 минуты. А TotalMinutes вернет 82 минуты.

В общем все операции нужно делать через TimeSpan.

По скольку данные из в TimeSpan можно получить в виде double то их можно округлить http://acroblog.acrovations.com/post/2012/09/11/Как-получить-целую-часть-или-округлить-double.aspx

Также хорошо можно использовать класс  Calendar который позволяет работать с неделями, месяцами, днями и тп.

DateTime myDT = DateTime.Now();
// Используются установленные по умолчанию календарь InvariantCulture.      
Calendar myCal = CultureInfo.InvariantCulture.Calendar;
// пример
myDT = myCal.AddYears( myDT, 5 );
myDT = myCal.AddMonths( myDT, 5 );
myDT = myCal.AddWeeks( myDT, 5 );
myDT = myCal.AddDays( myDT, 5 );
myDT = myCal.AddHours( myDT, 5 );
myDT = myCal.AddMinutes( myDT, 5 );
myDT = myCal.AddSeconds( myDT, 5 );
myDT = myCal.AddMilliseconds( myDT, 5 )

MSDN: http://msdn.microsoft.com/en-us/library/system.globalization.calendar.addweeks.aspx

Как получить целую часть или округлить double

Для этого есть стандартные функции в пространстве Math

Нас интересует:

Math.Floor – который округляет в сторону меньшего числа.

Math.Truncate – который округляет в сторону большего числа.

В зависимости от того что именно вам нужно – то и используйте.

Но скорее вам нужен именно Math.Floor, который и вернет целое число.

 

Шаблон C# MVVM

Хороший шаблон ViewModel для MVVM паттерна в WPF

public class BaseViewModel : INotifyPropertyChanged
{
public virtual void OnNavigatedTo(NavigationEventArgs args) { }  
public virtual void OnNavigatedFrom(NavigationEventArgs args) { }
public virtual void OnViewUnloaded(object sender, RoutedEventArgs e) { }
public virtual void OnViewLoaded(object sender, RoutedEventArgs e) { }
#region Propertychanged
protected void OnPropertyChanged(Expression> action)
{
var propertyName = GetPropertyName(action);
OnPropertyChanged(propertyName);
}
private static string GetPropertyName(Expression> action)
{
var expression = (MemberExpression)action.Body;
var propertyName = expression.Member.Name;
return propertyName;
}
private void OnPropertyChanged(string propertyName)
{
try
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
catch { }
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}

 

или

public class BaseViewModel : INotifyPropertyChanged
{
#region Propertychanged
protected void OnPropertyChanged<T>(Expression<Func<T>> action)
{
var propertyName = GetPropertyName(action);
this.OnPropertyChanged(propertyName);
}
private static string GetPropertyName<T>(Expression<Func<T>> action)
{
var expression = (MemberExpression)action.Body;
var propertyName = expression.Member.Name;
return propertyName;
}
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}

Использовать потом в виде OnPropertyChanged(()=> PorpertyName)

Паралельные операции в C# и как это использовать

 Паралельность может быть в двух видах.

1. Паралельные циклы

2. Паралельный LINQ

Как этим пользоваться?

Для паралельных операций надо использовать конструкции вида:

 

Parallel.ForEach(collection,
currentElement =>
{
// что-то делаем
});

 

Parallel.For(0, 50, i =>
{
// что-то делаем
});

 

для остановки Parallel.For:

Parallel.For(0, source.Length, (i, loopState) =>
{
// Take the first 100 values that are retrieved
// from anywhere in the source.
if (i < 100)
{
// Accessing shared object on each iteration
// is not efficient. See remarks.
double d = Compute(source[i]);
results.Push(d);
}
else
{
loopState.Stop();
return;
}

} // Close lambda expression.
); // Close Parallel.For

Очень важно использовать коллекции типа ConcurrentBag(T)
Из неймспейса  System.Collections.Concurrent
Иначе будут ошибки.

Что касается LINQ  то к запросу нужно добавить .AsParallel()

var test = from i in test.TestTables.AsParallel()
where i.PayDate >= date.Date 
select new { PaySum = i.PaySum};

 

Для сохранения порядка при выполнении запроса можно дописать .AsOrdered(), но это замедлит выполенение запроса.


Опять же надо быть осторожным, т.к. возможны ошибки связанными с доступом к переменным условия.

.