Telerik RadGridView - UserControl в ячейке

Иногда в RadGridView нужно засунуть что-то специфическое вот как это сделать:

Значит для начала надо сделать класс вашего нового типа колонки

public class MyNewColumn : GridViewBoundColumnBase
{
	public override FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)
	{
		this.BindingTarget = MyNewControl.MyNewProperty;
		var control = new MyNewControl();
		control.SetBinding(this.BindingTarget, this.CreateValueBinding());
		return control;
	}
	private Binding CreateValueBinding()
	{
		var valueBinding = new Binding();
		valueBinding.Mode = BindingMode.TwoWay;
		valueBinding.NotifyOnValidationError = true;
		valueBinding.ValidatesOnExceptions = true;
		valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
		valueBinding.Path = new PropertyPath(this.DataMemberBinding.Path.Path);
		return valueBinding;
	}
}

MyNewControl – это мой User Control который мы хотим поместить в ячейку.
MyNewControl.MyNewProperty – а это то свойство которое мы будем биндить.

Так,в юзер контроле надо это свойство сделать как DependencyProperty:

public static readonly DependencyProperty MyNewPropertyProperty =
            DependencyProperty.Register("MyNewProperty", typeof(int), typeof(MyNewControl), new PropertyMetadata(0, OnSelectedDateChanged));
public int MyNewProperty
{
	get
	{
		return (int)this.GetValue(MyNewProperty);
	}
	set
	{
		this.SetValue(MyNewProperty, value);
	}
}

Теперь как вы заметили мы указали метод OnSelectedDateChanged

private static void OnSelectedDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
	var control = (MyNewControl)d;
	control.OnSelectedDateChanged(control. MyNewProperty);
}

private void OnSelectedDateChanged(int item)
{
	// А вот тут мы уже делаем то, что нам нужно
	// обращаясь к свойству MyNewProperty
	// мы в нашем контроле
}

Ну и подключаем это в RadGridView
(сам контрол у меня в корне проекта)

xmlns:uc="clr-namespace:MyTestProgram"


<telerik:RadGridView ItemsSource="{Binding DocumentList, Mode=TwoWay}"  
					 AutoGenerateColumns="False" >
	<telerik:RadGridView.Columns>
		<uc:MyNewColumn   Width="1*" Header="My property" DataMemberBinding="{Binding CurrentOwners}">
			<uc:MyNewColumn.CellEditTemplate>
				<DataTemplate>
					<Grid>
						<uc:MyNewControl  MyNewProperty ="{Binding CurrentOwners}"  />
					</Grid>
				</DataTemplate>
			</uc:MyNewColumn.CellEditTemplate>
			<uc:MyNewColumn.CellTemplate>
				<DataTemplate>
					<Grid IsEnabled="False">
							<uc:MyNewControl  MyNewProperty ="{Binding CurrentOwners}"  />
					</Grid>
				</DataTemplate>
			</uc:MyNewColumn.CellTemplate>
		</uc:OwnerColumn>
	</telerik:RadGridView.Columns>
</telerik:RadGridView>

 

.Net локализация ресурсов .NET

Внезапно открыл для себя дополенение к Visual Studio Resource Translator от Microsoft. ( http://visualstudiogallery.msdn.microsoft.com/c23de518-d3bc-4b1a-a8d8-6ce43fdb2ff4?SRC=VSIDE )
Ставить его можно прямо из Visual Studio.
После установки жмете правой кнопкой на файле ресурсов который нужно локализировать выбираете язык и вперед.

Еще немного о счетчиках в .NET

Внезапно, если подключить библиотеку Microsoft.VisualBasic
То тогда можно получить нормальный доступ к счетчиками памяти

 

var mem1 = new Microsoft.VisualBasic.Devices.ComputerInfo().AvailablePhysicalMemory;
var mem2 = new Microsoft.VisualBasic.Devices.ComputerInfo().AvailableVirtualMemory;
var mem3 = new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory;
var mem4 = new Microsoft.VisualBasic.Devices.ComputerInfo().TotalVirtualMemory;


а также узнать о языковых параметрах и версии OS

.NET Запуск от имени администратора

WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
bool isRunAsAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

// Если нет прав админа 
if (!isRunAsAdmin)
{
	ProcessStartInfo proc = new ProcessStartInfo();
	proc.UseShellExecute = true;
	proc.WorkingDirectory = Environment.CurrentDirectory;
	proc.FileName = System.Windows.Forms.Application.ExecutablePath;
	proc.Verb = "runas";
	proc.Arguments = string.Empty;

	try
	{
		Process.Start(proc);
	}
	catch
	{

	}

	Application.Current.Shutdown();  // Выходим
}

.NET завершить процесс

 
var ps1 = System.Diagnostics.Process.GetProcessesByName("Process Name").ToList();
if (ps1.Count > 1)
{
	foreach (Process p1 in ps1)
	{
		if (p1.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
		{
			p1.Kill();
		}
	}
}

WPF xaml разметка из кода на C#

Разметка Grid из кода
Установка фиксированного размера:

TableGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new System.Windows.GridLength(50) });
TableGrid.RowDefinitions.Add(new RowDefinition() { Height = new System.Windows.GridLength(50) });

Установа отностиельного размера, типа вездочка  (*) или Auto:

LayoutRoot.ColumnDefinitions[1] = new ColumnDefinition() { Width = new System.Windows.GridLength(2, System.Windows.GridUnitType.Star) };
LayoutRoot.RowDefinitions[1] = new  RowDefinition() { Height = new System.Windows.GridLength(2, System.Windows.GridUnitType.Auto) };

Помещение элемента в сетку:

TextBox  txtbox = new TextBox();
Grid.SetRow(txtbox, 2); 
Grid.SetColumn(txtbox, 3);
Grid.SetColumnSpan(txtbox, 2);
Grid.SetRowSpan(txtbox, 3);
TableGrid.Children.Add(txtbox); // добавляем элемент в грид

MVVM Command – еще один способ

 

public class TestViewModel : BaseViewModel
{
public ICommand MyCommand { get; set; }
public TestViewModel ()
{
this.MyCommand = new DelegateCommand(this.MyCommandExecuted, this.CanMyCommandCanExecuted);        
}
public void MyCommandExecuted(object param)
{
// что-то делаем
}
private bool CanMyCommandCanExecuted(object param)
{
return param != null;
}
}


или собранное в кучу на делегатах:

public ICommand MyCommand
        {
            get
            {
                return new DelegateCommand((executedParam) =>
                {
                    //executed code
                }, 
                (canExecutedParam) =>
                {
                    //CanCxecuted code
                    return true;
                }); 
            }
        }

Task (async await) и Parallel в C#

Как работать с Task

var t = Task.Factory.StartNew(() => DoAction());

 

Action<object> action = (object obj) =>
{
Console.WriteLine("Task={0}, obj={1}, Thread={2}", Task.CurrentId, obj.ToString(), Thread.CurrentThread.ManagedThreadId);
};
// Создать задачу, без ее немедленного запуска
Task t1 = new Task(action, "alpha");
// Cоздать задачу и сразу запустить ее
Task t2 = Task.Factory.StartNew(action, "beta");
// дождаться завершения t2
t2.Wait();
// Запустить задачу t1 
t1.Start();
Console.WriteLine("t1 has been launched. (Main Thread={0})", Thread.CurrentThread.ManagedThreadId);
// Ждем задачу до конца.
// Вы можете дополнительно обеспечить тайм-аута или отмены маркера
// Для смягчения ситуации, когда задача занимает слишком много времени, чтобы закончить.        
t1.Wait();
// Создать задачу но не запустить ее
Task t3 = new Task(action, "gamma");
// Запустите его синхронно
t3.RunSynchronously();
// Хотя задача была выполнена синхронно, это хорошая практика, чтобы ждать его, завершения.
t3.Wait();

 

// вернуть задачу 
public Task<int> DoSome()
{
return Task.Factory.StartNew(() =>
{
Thread.Sleep(500);
return 100500;
});
}

 


Параллелизм

Parallel.Invoke(() => DoSomeWork(), () => DoSomeOtherWork());


Ссылки:

http://msdn.microsoft.com/ru-ru/library/system.threading.tasks.task.aspx

http://msdn.microsoft.com/ru-ru/library/dd537609.aspx

SignalR добавить header для Forms авторизации

Если у вас на сервере настроение Froms авторизация, а вы из клиента пытаетесь подключиться к сервису то обычно нужно добавить в заголовок запроса авторотационные Cookies.
Как это сделать
1. На сервере в Hub добавить авторизацию:

[Authorize]
[HubName("MyTestHub")]
public class TestHub : Hub
{
public TestHub()
{
int a = 5;
}
}

2. Каким-то образом получить заголовок авторизации
http://acroblog.acrovations.com/post/2013/03/22/Forms-авторизация-WCF-Data-Service.aspx
например как тут, в функции GetCookie

var hub = new HubConnection("http://localhost:5555/signalr");
hub.CookieContainer = new CookieContainer();
hub.CookieContainer.SetCookies(new Uri("http://localhost:5555/"), MyCookieHeader.Cookie);
var x = hub.CookieContainer.GetCookieHeader(new Uri("http://localhost:5555/"));
var cook = new Cookie("test", "test");
cook.Domain = "localhost";
cook.Path = "/";
hub.CookieContainer.Add(cook);
proxy = hub.CreateHubProxy("MyTestHub");
hub.Start().Wait();

все.
Главное добавить какой-то cookie чтобы было с чем заголовок отправлять.

MVVM Command Pattern

public ICommand CommandName { get; set; }
private void CommandExecutedLogic(object param)
{
// Do Some
}
private bool CanExecutedLogic(object param)
{
return param != null;
}


В конструкторе:

this.CommandName = new DelegateCommand(this.
CommandExecutedLogic, this. CanExecutedLogic);

WCF Data Services и Composite Key и Telerik Open Access ORM (OData V3)

Если вы используете связи многие-ко-многим (many-to-many) с помощю составных ключей:

CREATE TABLE ClientInGroup
(
ClientID bigint foreign key references Client(ID) not null, 
ClientGroupID bigint foreign key references ClientGroup(ID) not null, 
PRIMARY KEY  
(
ClientID,
ClientGroupID 
)
)

И решили использовать WCF Data Service то можете столкнуться с проблемой когда вы не можете обновить связанные записи.
Для решение этой досадной проблемы нужно сделать вот чего:

На сервер в сгенерированном телериком файле OpenAccessUpdateProvider найти функцию GetNavigationalMember и добавить туда строку navigationProperty.IsManaged = true;

private MetaNavigationMember GetNavigationalMember(string propertyName, string className)
{
MetaNavigationMember navigationProperty = this.GetMember(propertyName, className) as MetaNavigationMember;
navigationProperty.IsManaged = true;
if (navigationProperty.Association is MetaJoinTableAssociation && !navigationProperty.IsManaged)
{
string exceptionMessage = string.Format("Change made on property {0} of type {1} that has IsManaged set to False will not be persisted.",
navigationProperty.PropertyName, navigationProperty.DeclaringType.FullName);
throw new InvalidOperationException(exceptionMessage);
}
return navigationProperty;
}

После этого все будет работать. И в вашем приложении вы можете спокойно связывать данные

dataModel.AddLink(CurrentSportSection, "Venues", item);


или

dataModel.DeleteLink(CurrentSportSection, "Venues", item);

 

WPF Data Service V2 в место V3

В процессе генерации прокси класа для WCF Data Service Visual Studio бывает указывает версию V2 в место V3.
Чтоб это исправить нужно найти класс сервиса и немного поменять конструктор:

[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.Data.Services.Design", "1.0.0")]
public MyDataBaseService (global :: System.Uri serviceRoot):
base (serviceRoot, System.Data.Services.Common.DataServiceProtocolVersion.V3)
{
this.ResolveName = new global :: System.Func <global::System.Type, string> (this.ResolveNameFromType);
this.ResolveType = new global :: System.Func <string, global::System.Type> (this.ResolveTypeFromName);
this.OnContextCreated ();
}

В базовый конструктор нужно добавить System.Data.Services.Common.DataServiceProtocolVersion.V3 – что укажет что мы используем протокол версии V3.

Хотя после последнего обновления, данные манипуляции ненужны.

Timer Windows 8 (WinRT)

private DispatcherTimer timer;
private void StartTimer()
{
if (timer == null)
{
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 0,33);
timer.Tick += timer_Tick;
}
timer.Stop();
timer.Start();
}
public void timer_Tick(object sender, object args)
{
//какой-то код
}