tag:blogger.com,1999:blog-58336255345083280542024-03-19T03:47:47.750-07:00MišákMišákovi vývojářské zápiskyMišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.comBlogger90125tag:blogger.com,1999:blog-5833625534508328054.post-53579837410095763132014-05-07T01:50:00.002-07:002014-05-07T01:56:29.819-07:00WPF - Jak změnit vzhled Focus rámečku?Každému se tečkovaný Focus rámeček nemusí líbit.
U ovládacího prvku stačí nastavit:<br />
FocusVisualStyle="{StaticResource MyFocusVisualStyle}"<br />
<br />
A příklad:
<br />
<div class="sh_result"><pre><SolidColorBrush x:Key=<span class="net_string">"SelectBrushAlpha"</span> Color=<span class="net_string">"#99288AF7"</span>/>
<Style x:Key=<span class="net_string">"MyFocusVisualStyle"</span>>
<Setter Property=<span class="net_string">"Control.Template"</span>>
<Setter.Value>
<ControlTemplate>
<Rectangle Fill=<span class="net_string">"{StaticResource SelectBrushAlpha}"</span> SnapsToDevicePixels=<span class="net_string">"true"</span> />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style></pre></div>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-88877530696661732482014-05-07T01:43:00.001-07:002014-05-07T01:43:12.120-07:00WPF - KeyboardNavigation - Navigace pomocí kláves v ItemsControl nebo v jiném 'kontejnéru'Jako uživatel windows aplikací se řadím spíše mezi takzvané klikače, proto mi velice často unikají ve vývoji potřeby příznivců tzv. klávesovačů - čili uživatelů vyplňujících okna pomocí klávesnice a klávesových zkratek. Takže tyto detajly musím dolaďovat jako vývojář v závěrečné fázi před nasazením.<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-xCI4fDm4zxE/U2nl7CujUwI/AAAAAAAAMXs/enmeole0sIk/s1600/elementeditor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-xCI4fDm4zxE/U2nl7CujUwI/AAAAAAAAMXs/enmeole0sIk/s1600/elementeditor.png" height="147" width="320" /></a></div>
<br />
Pokud si okno skládáte ručně, tak si zpravidla vystačíte s nastavováním TabIndexů, které určí pořadí editace při stisknutí klávesy Tab. Jelikož mám editor postavený dynamicky přes ItemsControl, tak jsem TabIndex nevyužil. Klávesou Tab naviguji z jedné položky ItemsControl na druhou.<br />
<br />
Celkem zajímavá je ale možnost ale ovlivnit možnost navigace klávesnící ItemsControl, připadně v jiném kontejnéru.<br />
<br />
Navigaci klávesnící ovlivním snadno přes třídu - KeyboardNavigation.<br />
<a href="http://msdn.microsoft.com/en-us/library/aa969768(v=vs.110).aspx">V MSDN si o tom můžete přečíst ZDE.</a><br />
<br />
Navigaci přes Tabulátor ovlivníte - KeyboardNavigation.TabNavigation<br />
Směrovou navigaci přes šipky ovlivníte - KeyboardNavigation.DirectionalNavigation<br />
<br />
A možnosti jsou následující: Contained, Continue, Cycle, Local, None, Once<br />
<br />
Nejlépe je si chování vyzkoušet na příkladu:<br />
<br />
<div class="sh_result"><pre><GroupBox Header=<span class="net_string">"Check Boxes"</span> KeyboardNavigation.TabNavigation=<span class="net_string">"Once"</span>
Height=<span class="net_string">"126"</span> HorizontalAlignment=<span class="net_string">"Left"</span>
VerticalAlignment=<span class="net_string">"Top"</span> Width=<span class="net_string">"200"</span>>
<StackPanel Margin=<span class="net_string">"8"</span>>
<CheckBox Content=<span class="net_string">"Check Box 1"</span>/>
<CheckBox Content=<span class="net_string">"Check Box 2"</span>/>
<CheckBox Content=<span class="net_string">"Check Box 3"</span>/>
<CheckBox Content=<span class="net_string">"Check Box 4"</span>/>
<CheckBox Content=<span class="net_string">"Check Box 5"</span>/>
</StackPanel>
</GroupBox>
<GroupBox x:Name=<span class="net_string">"gbRadio"</span> Header=<span class="net_string">"Radio Buttons"</span> Height=<span class="net_string">"126"</span> VerticalAlignment=<span class="net_string">"Top"</span> Margin=<span class="net_string">"206,0,107,0"</span>>
<StackPanel Margin=<span class="net_string">"8"</span>>
<RadioButton x:Name=<span class="net_string">"radio1"</span> Content=<span class="net_string">"Radio Button 1"</span>/>
<RadioButton Content=<span class="net_string">"Radio Button 2"</span>/>
<RadioButton Content=<span class="net_string">"Radio Button 3"</span>/>
<RadioButton Content=<span class="net_string">"Radio Button 4"</span>/>
<RadioButton Content=<span class="net_string">"Radio Button 5"</span>/>
</StackPanel>
</GroupBox></pre></div>
<br />
A přitom taková blbost, ale potěší :).Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-4184297837620395682014-03-17T09:23:00.000-07:002014-03-18T02:14:22.493-07:00Můj první CmdLet do Powershellu.<b>Můj první CmdLet do Powershellu</b><br />
<br />
Po jedné diskuzi s kamarádem, který pracuje v Praze jako serverový správce na platformě windows, jsem dospěl k názoru, že Powershell může býti užitečný nástroj. Protože jsem kluk zvědaví, rozhodl jsem se, že přehodnotím předsudek, který vůči powershellu mám - skriptovací sračka ala vbscript, jscript.<br />
<br />
K čemu by mohlo být spouštění takového skriptu dobré v našich rádiových podmínkách? Položil jsem si otázku. Máme server, na kterém běží pán démonů. Tento pán démonů nám spouští joby, když přijde nějaká událost (podnět) - časová událost, změní se soubor, nebo přijde podnět přes HTTP. Joby máme zapsané jako posloupnost akcí, definovaných v nějakém popisném XML souboru.<br />
<br />
Co kdyby pán démonů místo našich jobů spouštěl powershell scripty?<br />
Co kdybych začal jednoduše tím, že si napíši svůj první CmdLet.<br />
<br />
1. Vytvořím si C# project ClassLibary a přidám si referenci na System.Management.Automation.dll assembly, která obsahuje třídy PSCmdlet a PSSnapIn.<br />
<br />
Třída PSSnapIn slouží k registraci přídavného balíčku PSSnapIn. Její význam jsem úplně nepochopil. Možná, aby mohlo být vše složitější.<br />
<br />
<div class="sh_result">
<pre>[RunInstaller(<span class="net_key">true</span>)]
<span class="net_key">public</span> <span class="net_key">class</span> CmdLetSnapIn : PSSnapIn
{
<span class="net_key">public</span> <span class="net_key">override</span> <span class="net_key">string</span> Name
{
get { <span class="net_key">return</span> <span class="net_string">"CmdLet"</span>; }
}
<span class="net_key">public</span> <span class="net_key">override</span> <span class="net_key">string</span> Vendor
{
get { <span class="net_key">return</span> <span class="net_string">""</span>; }
}
<span class="net_key">public</span> <span class="net_key">override</span> <span class="net_key">string</span> VendorResource
{
get { <span class="net_key">return</span> <span class="net_string">"CmdLet,"</span>; }
}
<span class="net_key">public</span> <span class="net_key">override</span> <span class="net_key">string</span> Description
{
get { <span class="net_key">return</span> <span class="net_string">"Registers the CmdLets and Providers in this assembly"</span>; }
}
<span class="net_key">public</span> <span class="net_key">override</span> <span class="net_key">string</span> DescriptionResource
{
get { <span class="net_key">return</span> <span class="net_string">"CmdLet,Registers the CmdLets and Providers in this assembly"</span>; }
}
}</pre>
</div>
<br />
Třída PSCmdlet, je třída CmdLetu. Třída slouží k vykonání CmdLetu.<br />
<div class="sh_result">
<pre>[Cmdlet(VerbsCommon.Get, <span class="net_string">"CmdTest"</span>, SupportsShouldProcess = <span class="net_key">true</span>)]
<span class="net_key">public</span> <span class="net_key">class</span> CmdTest : PSCmdlet
{
<span class="net_directive">#region</span> Parameters
<span class="net_comment">/*
[Parameter(Position = 0,
Mandatory = false,
ValueFromPipelineByPropertyName = true,
HelpMessage = "Help Text")]
[ValidateNotNullOrEmpty]
public string Name
{
}
*/</span>
<span class="net_directive">#endregion</span>
<span class="net_key">protected</span> <span class="net_key">override</span> <span class="net_key">void</span> ProcessRecord()
{
<span class="net_key">try</span>
{
WriteObject(System.Diagnostics.Process.GetProcesses(), <span class="net_key">true</span>);
}
<span class="net_key">catch</span> (Exception)
{
}
}
}</pre>
<pre></pre>
</div>
Třída má definovaný důležitý attribut <b>Cmdlet</b>,<b> </b>kterým říkáme, jakým slovesem jej budeme volat - VerbsCommon.Get, dalším parametrem attributu je jméno command letu - CmdTest. Takovýto command let zavoláme z powershell konzole jako Get-CmdTest . Tato třída CmdTest má povinnou funkci ProcessRecord(), která je vykonávací funkcí CommandLetu. Pro zápis do výstupu voláme WriteObject. Tento command let neobsahuje žádné parametry, ale mohli bychom si parametry definovat velice jednoduchým způsobem: pomocí property atributu Parameter - [Parameter(Position = 0,
Mandatory = false,
ValueFromPipelineByPropertyName = true,
HelpMessage = "Help Text")].<br />
<br />
To je tak k prvnímu CmdLetu asi vše. Nyní jej můžeme zkompilovat a nainstalovat. Nahrajeme jej do cesty s Moduly - cesta je uložená v systémové proměné PSModulePath. Pak už můžeme vesele spustit konzoli Powershellu.<br />
<br />
<br />
<ul>
<li>SnapIn registrujeme pomocí .NET utiliti InstallUtil jmenosnapinu (cesta dll)</li>
<li>Registrované přílepky si vylistujeme: Get-PSSnapIn -registered - tady se objeví v seznamu CmdLet (jméno z třídy PSSnapIn).</li>
<li>SnapIn přidámě pomocí Add-PSSnapIn CmdLet</li>
<li>CmdLet zavoláme pomocí Get-CmdTest (!!!Název definovaný attributem Cmdlet!!!)</li>
</ul>
<br />
<br />
<br />Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-64722293078610354252014-03-13T06:59:00.002-07:002014-03-13T06:59:52.203-07:00První pokusy s PowerShellem(get-date).ToString('yyyy-MM-dd')Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-38580508550964653732014-01-13T01:51:00.000-08:002014-01-13T01:51:37.336-08:00.NET Memory leaks<b>Problém: Zdravím, máme celkem rozsáhlý projekt v .NET, který také volá nativní dll. Aplikaci neustále narůstá paměť.</b>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-5161900581165505642013-12-31T16:03:00.001-08:002013-12-31T16:03:15.802-08:00Nový rok 2014Všechno nejlepší do Nového roku 2014, hodně čistého a znovupoužitého kódu, který přežije nejeden projekt.<br />
<br />
A hlavně zdravíčko a dobré přátele.Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-27728559284733011352013-12-04T07:41:00.000-08:002013-12-04T07:41:48.605-08:00Immutable collections in .NET<br />
<br />
<a href="http://blogs.msdn.com/b/dotnet/archive/2013/09/25/immutable-collections-ready-for-prime-time.aspx">http://blogs.msdn.com/b/dotnet/archive/2013/09/25/immutable-collections-ready-for-prime-time.aspx</a><br />
<a href="http://msdn.microsoft.com/en-us/library/dn467185(v=vs.110).aspx">http://msdn.microsoft.com/en-us/library/dn467185(v=vs.110).aspx</a><br />
<a href="http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx">http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx</a>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-25101457401278237932013-12-04T07:14:00.001-08:002013-12-04T07:18:59.887-08:00Spojování dvou a více .NET Assembly.Pokud programujete v C nebo C++, tak jistě víte, že knihovny lze linkovat do výsledné aplikace staticky nebo dynamicky. Pokud linkujete staticky, tak se vám knihovny připojí k výsledné aplikaci a nepotřebujete nic dalšího k aplikaci přidávat. Pokud linkujete dynamicky musíte mít společně s aplikací také dynamické knihovny dll.<br />
<br />
V prostředí .NET ale jsou knihovny referencované dynamicky a s aplikací teda potřebujete i .NET dll knihovny.<br />
<br />
Tak mě napadlo, jestli by nešlo .NET assembly slinkovat také staticky. Vše nasvědčuje tomu, že žádné statické slinkování nenní možné jak jsme byli zvyklí z céčka.<br />
Googloval jsem na netu a řešením je spojení více assembly do jedné použitím utility ILMerge.exe<br />
<br />
<a href="http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx">ILMerge</a><br />
<br />Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-22438562766879561362013-11-28T03:11:00.004-08:002013-11-28T03:26:44.178-08:00GIT - aplikace patcheNa správu mého GIT repozitáře, použivam SourceTree od Atlassianu. Aktuální verze 1.3.2 neumí vytvářet patche do souboru a následně je aplikovat v jiné větvi. Přes git konzoli to alr není žádný problém.<br />
<b><br /></b>
<b>$ git format-patch BruceLee --stdout > z:/lib.patch</b><br />
<b><br /></b>
Git vytvořil z podsledního komitu větve BruceLee rozdílový soubor a uložil ho do z:/lib.patch.<br />
<br />
Nyní se můžete přepnout do větve, kde chcete patch aplikovat.<br />
Aplikaci patche můžete otestovat.<br />
<br />
<span style="line-height: 1.428571429;"><b>$git apply --check z:/lib.patch</b></span><br />
<span style="line-height: 1.428571429;"><b><br /></b></span>
<span style="line-height: 1.428571429;">A pokud je vše v pořádku, můžeme patch aplikovat.</span><br />
<span style="line-height: 1.428571429;"><b><br /></b></span>
<b>git am --signoff < z:/lib.patch</b><br />
<pre class="plaincode" style="background-color: #f9f9f9; background-image: none; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: none; box-sizing: border-box; color: #333333; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; font-size: 12px; line-height: 1.428571429; margin-bottom: 10px; overflow: auto; padding: 6px; word-break: normal; word-wrap: normal;"><span style="line-height: 1.428571429;"><b>
</b></span></pre>
Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-25000052968195870242013-11-20T04:55:00.001-08:002013-11-20T05:30:54.124-08:00Postgres on Scientific Linux 9.2<a href="http://www.if-not-true-then-false.com/2012/install-postgresql-on-fedora-centos-red-hat-rhel/">http://www.if-not-true-then-false.com/2012/install-postgresql-on-fedora-centos-red-hat-rhel/</a><br />
<br />
<pre class="code" style="background-color: #f3f3f3; border: 1px dashed rgb(193, 180, 150); color: #333333; font-family: 'Ubuntu Mono', monospace, courier, sans-serif; font-size: 13px; line-height: 20px; margin-bottom: 1em; overflow: auto; padding: 0.5em; text-align: justify;">sudo passwd postgres #Změní heslo</pre>
Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-18443106656746536722013-11-07T08:01:00.001-08:002013-11-07T08:01:05.250-08:00What is SignalR?<a href="http://signalr.net/">http://signalr.net/</a>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-46156512093626568802013-11-07T07:10:00.000-08:002013-11-07T07:57:18.879-08:00ASP .NET MVC - hostování webové aplikace v konzolové aplikaciPojďme se podívat zase na jeden problém z vývojářského života. Máme svůj vlastní klient - server systém a server nám běží jako služba ve windows nebo jako konzolová aplikace. Jedná se o náš vlastní server. Tento server má přístup do SQL a data zpřístupňuje pro klienty pomocí webových služeb. Protože dotazy na některá data jsou časově náročné, server si udržuje vlastní cache.<br />
<br />
Já bych potřeboval do tohoto serveru přidat další modul (dll), který se při startu zavede pomocí MEF. Já bych potřeboval, aby tento modul poskytoval webovou aplikaci ASP .NET MVC - Razor. Myslel jsem si, že to nebude vůbec žádný problém, protože já již umím hostovat MVC Web API. K tomu se používá třída<br />
<pre class="prettyprint prettyprinted" style="background-color: #f3f3f3; border: 1px dashed rgb(204, 204, 204); color: #222222; font-family: Consolas, monospace; font-size: 13px; line-height: 18.203125px; margin-bottom: 30px; margin-top: 18px; outline: 0px; overflow: auto; padding: 5px; vertical-align: baseline;"><span class="typ" style="background-color: transparent; border: 0px; color: #2b91af; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">HttpSelfHostServer</span></pre>
<a href="http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api">Tutorial o ASP .NET Self hosting WebAPI</a><br />
<br />
Hostování Web API mám vyzkoušené a funguje bez problému, tak jsem zkoušel také nahostovat webovou aplikaci která hostuje MVC stránky s enginem Razor.<br />
<br />
Řešení jsem prozatím nenašel, berte to špíše jako položenou otázku a sběr informací.<br />
<br />
Jedna možnost je použití knihovny <a href="http://blogs.msdn.com/b/hongyes/archive/2012/03/12/using-razor-template-engine-in-web-api-self-host-application.aspx">RazorEngine</a>. Pokud se chcete vyhnout neoficiálním knihovnám třetích stran, pojďme ještě hledat dál.<br />
<br />
Dále je možné hostovat webovou aplikaci pomocí<br />
<h4>
<a href="http://blogs.msdn.com/b/carlosag/archive/2008/04/14/hostyourownwebserverusingiis7.aspx">IIS 7.0 Hostable Web Core</a></h4>
Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-76195938045580752002013-10-21T06:24:00.001-07:002013-10-21T07:53:46.822-07:00C# JSON Serializace a deserializace polymorfních objektů<b><span style="font-family: inherit;">C# JSON Serializace a deserializace polymorfních objektů -rozepsané</span></b><br />
<b><br /></b>
<br />
Po dlouhé době jsem narazil na zajímavý problém. Potřebuji uložit data do formátu JSON ale každá datová položka je jiný typ. Jedná se o tzv. polymofní typ. Například chci si uložit databázi zvířat (animals) a mám definovaný obecný objekt animal a pak mám definované konkrétní typy Cat, Lion, Horse. A každý typ má trochu jiné vlastnosti.<br />
<br />
Podívejme se na můj konkrétní případ: Mám pole nějakých objektů, které představují nějaké nastavení. Každá položka v poli má své jméno Name a hodnotu Value.<br />
<br />
<div class="sh_result">
<pre><span class="net_key">public</span> <span class="net_key">class</span> OptionValue
{
[DataMember]
<span class="net_key">public</span> <span class="net_key">string</span> Name { get; set; }
[DataMember]
<span class="net_key">public</span> <span class="net_key">object</span> Value { get; set; }
}</pre>
<pre></pre>
</div>
Defaultní JSON serializér mi udělal jednoduchý JSON, ale nešlo rozeznat Typy Value. Udělal jsem si pro každý datový typ speciální variantu:<br />
<br />
<br />
<div class="sh_result">
<pre>[DataContract]
<span class="net_key">public</span> <span class="net_key">class</span> IntValue
{
<span class="net_key">public</span> IntValue()
{
}
<span class="net_key">public</span> IntValue(<span class="net_key">string</span> name)
{
Name = name;
}
[DataMember]
<span class="net_key">public</span> <span class="net_key">string</span> Name { get; set; }
[DataMember]
<span class="net_key">public</span> <span class="net_key">new</span> Int32 Value { get; set; }
}
[DataContract]
<span class="net_key">public</span> <span class="net_key">class</span> BoolValue
{
<span class="net_key">public</span> BoolValue()
{
}
<span class="net_key">public</span> BoolValue(<span class="net_key">string</span> name)
{
Name = name;
}
[DataMember]
<span class="net_key">public</span> <span class="net_key">string</span> Name { get; set; }
[DataMember]
<span class="net_key">public</span> <span class="net_key">new</span> <span class="net_key">bool</span> Value { get; set; }
}
[DataContract]
<span class="net_key">public</span> <span class="net_key">class</span> StringValue
{
<span class="net_key">public</span> StringValue()
{
}
<span class="net_key">public</span> StringValue(<span class="net_key">string</span> name)
{
Name = name;
}
[DataMember]
<span class="net_key">public</span> <span class="net_key">string</span> Name { get; set; }
[DataMember]
<span class="net_key">public</span> <span class="net_key">new</span> String Value { get; set; }
}
[DataContract]
<span class="net_key">public</span> <span class="net_key">class</span> TimeValue
{
<span class="net_key">public</span> TimeValue()
{
}
<span class="net_key">public</span> TimeValue(<span class="net_key">string</span> name)
{
Name = name;
}
[DataMember]
<span class="net_key">public</span> <span class="net_key">string</span> Name { get; set; }
[DataMember]
<span class="net_key">public</span> <span class="net_key">new</span> TimeSpan Value { get; set; }
}
[DataContract]
<span class="net_key">public</span> <span class="net_key">class</span> DateValue
{
<span class="net_key">public</span> DateValue()
{
}
<span class="net_key">public</span> DateValue(<span class="net_key">string</span> name)
{
Name = name;
}
[DataMember]
<span class="net_key">public</span> <span class="net_key">string</span> Name { get; set; }
[DataMember]
<span class="net_key">public</span> <span class="net_key">new</span> DateTime Value { get; set; }
}</pre>
<pre></pre>
</div>
Pokud použiji defaultní serializér:
<br />
<br />
<div class="sh_result">
<pre>msg = Request.CreateResponse(HttpStatusCode.OK,array, <span class="net_string">"application/json"</span>);</pre>
<pre></pre>
dostanu výsledek, kde nevím, jakého typu mám položky.
<br />
<br />
<pre></pre>
<pre><div class="sh_result">
<pre>[{<span class="net_string">"Name"</span>:<span class="net_string">"DefaultSection"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"SatelliteHolder"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"FillInterfaceName"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"Bonus"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"FillFilterName"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"SATELLITE FILL"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"FillSection:Position"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"end"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"FillSection:Position"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"end"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"FillSection:Position"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"end"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"ConfigFillSectionType"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"SpotsetHolder"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"MinAllowFillDistance"</span>,<span class="net_string">"Value"</span>:240},{<span class="net_string">"Name"</span>:<span class="net_string">"MinGroupFillDistance"</span>,<span class="net_string">"Value"</span>:10},{<span class="net_string">"Name"</span>:<span class="net_string">"SeparationFilterName"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"SATELLITE SEPARATION"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"FillFilterSkip"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"SATELLITE SKIP"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"ConfigSkipSectionType"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"SpotsetHolder"</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"Performance"</span>,<span class="net_string">"Value"</span>:<span class="net_key">false</span>},{<span class="net_string">"Name"</span>:<span class="net_string">"VisibleSections"</span>,<span class="net_string">"Value"</span>:<span class="net_string">"HourHeader|SatelliteHolder"</span>}]</pre>
</div>
</pre>
</div>
Na rozlišení typů jsem si našel jiný serializer, který se nacháyí v System.Web.Extensions.
<div class="sh_result"><pre><span class="net_key">string</span> json = <span class="net_key">new</span> JavaScriptSerializer(<span class="net_key">new</span> TypeResolver()).Serialize(o);
msg = Request.CreateResponse(HttpStatusCode.OK,json, <span class="net_string">"application/json"</span>);</pre></div>
K tomu musíte ješte připsat JavaScriptTypeResolver:
<div class="sh_result"><pre><span class="net_key">public</span> <span class="net_key">class</span> TypeResolver : JavaScriptTypeResolver
{
<span class="net_key">public</span> <span class="net_key">override</span> Type ResolveType(<span class="net_key">string</span> id)
{
<span class="net_key">if</span> (id == <span class="net_string">"string"</span>)
{
<span class="net_key">return</span> <span class="net_key">new</span> StringValue().GetType();
}
<span class="net_key">else</span> <span class="net_key">if</span> (id == <span class="net_string">"int"</span>)
{
<span class="net_key">return</span> <span class="net_key">new</span> IntValue().GetType();
}
<span class="net_key">else</span> <span class="net_key">if</span> (id == <span class="net_string">"bool"</span>)
{
<span class="net_key">return</span> <span class="net_key">new</span> BoolValue().GetType();
}
<span class="net_key">else</span> <span class="net_key">if</span> (id == <span class="net_string">"float"</span>)
{
<span class="net_key">return</span> <span class="net_key">new</span> FloatValue().GetType();
}
<span class="net_key">else</span> <span class="net_key">if</span> (id == <span class="net_string">"time"</span>)
{
<span class="net_key">return</span> <span class="net_key">new</span> TimeSpan().GetType();
}
<span class="net_key">else</span> <span class="net_key">if</span> (id == <span class="net_string">"date"</span>)
{
<span class="net_key">return</span> <span class="net_key">new</span> DateTime().GetType();
}
<span class="net_key">return</span> <span class="net_key">new</span> <span class="net_key">object</span>().GetType();
}
<span class="net_key">public</span> <span class="net_key">override</span> <span class="net_key">string</span> ResolveTypeId(Type type)
{
<span class="net_key">if</span> (type.Name == <span class="net_string">"StringValue"</span>)
<span class="net_key">return</span> <span class="net_string">"string"</span>;
<span class="net_key">else</span> <span class="net_key">if</span> (type.Name == <span class="net_string">"IntValue"</span>)
<span class="net_key">return</span> <span class="net_string">"int"</span>;
<span class="net_key">else</span> <span class="net_key">if</span> (type.Name == <span class="net_string">"BoolValue"</span>)
<span class="net_key">return</span> <span class="net_string">"bool"</span>;
<span class="net_key">else</span> <span class="net_key">if</span> (type.Name == <span class="net_string">"FloatValue"</span>)
<span class="net_key">return</span> <span class="net_string">"float"</span>;
<span class="net_key">else</span> <span class="net_key">if</span> (type.Name == <span class="net_string">"TimeValue"</span>)
<span class="net_key">return</span> <span class="net_string">"time"</span>;
<span class="net_key">else</span> <span class="net_key">if</span> (type.Name == <span class="net_string">"DateValue"</span>)
<span class="net_key">return</span> <span class="net_string">"date"</span>;
<span class="net_key">return</span> <span class="net_string">"anyType"</span>;
}</pre></div>
Zpětně jde výsledek zase serializovat:
<div class="sh_result"><pre><span class="net_key">object</span> obj = <span class="net_key">new</span> JavaScriptSerializer(<span class="net_key">new</span> TypeResolver()).Deserialize<Options>(json);</pre></div>
Výsledek už nevypadá tak hezky, ale informaci o typu zde již máme.
<div class="sh_result"><pre><span class="net_string">"[{\"__type\":\"string\",\"Name\":\"DefaultSection\",\"Value\":\"SatelliteHolder\"},{\"__type\":\"string\",\"Name\":\"FillInterfaceName\",\"Value\":\"Bonus\"},{\"__type\":\"string\",\"Name\":\"FillFilterName\",\"Value\":\"SATELLITE FILL\"},{\"__type\":\"string\",\"Name\":\"FillSection:Position\",\"Value\":\"end\"},{\"__type\":\"string\",\"Name\":\"FillSection:Position\",\"Value\":\"end\"},{\"__type\":\"string\",\"Name\":\"FillSection:Position\",\"Value\":\"end\"},{\"__type\":\"string\",\"Name\":\"ConfigFillSectionType\",\"Value\":\"SpotsetHolder\"},{\"__type\":\"int\",\"Name\":\"MinAllowFillDistance\",\"Value\":240},{\"__type\":\"int\",\"Name\":\"MinGroupFillDistance\",\"Value\":10},{\"__type\":\"string\",\"Name\":\"SeparationFilterName\",\"Value\":\"SATELLITE SEPARATION\"},{\"__type\":\"string\",\"Name\":\"FillFilterSkip\",\"Value\":\"SATELLITE SKIP\"},{\"__type\":\"string\",\"Name\":\"ConfigSkipSectionType\",\"Value\":\"SpotsetHolder\"},{\"__type\":\"bool\",\"Name\":\"Performance\",\"Value\":false},{\"__type\":\"string\",\"Name\":\"VisibleSections\",\"Value\":\"HourHeader|SatelliteHolder\"}]"</span></pre></div>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-24214566482777591762013-03-22T06:17:00.002-07:002013-03-28T08:49:46.861-07:00Věčný problém s parsováním parametrů URLOpakovaně řeším v serverové službě problém s parsováním parametrů.<br />
<br />
<br />
<ol>
<li>Když jsem si službu napsal jako WCF REST, tak jsem zjistil, že WCF neumí pracovat s dynamickým počtem parametrů. Tak jsem dynamické parametry zakódoval do stringu. Vše se zdálo v pohodě až do chvíle, kdy se v parametrech objevilo '/' nedokáže WCF příjmout HTTP request. Vadí mu lomítko navíc. Zde jsem řešení nenašel</li>
<li>Když jsem službu napsal jako HttpListener, tedy pouze jednoduchý zachytávač HTTP requestů, tak jsem narazil na podobný problém se znakem '&'.<br /><br />Parametry jsem si naparsoval pomocí utility:<br /><pre class="lang-cs prettyprint prettyprinted" style="background-color: #eeeeee; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; font-size: 14px; line-height: 18px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"><code style="border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin: 0px; padding: 0px; vertical-align: baseline;"><span class="typ" style="background-color: transparent; border: 0px; color: #2b91af; margin: 0px; padding: 0px; vertical-align: baseline;">NameValueCollection</span><span class="pln" style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"> qscoll </span><span class="pun" style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">=</span><span class="pln" style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"> </span><span class="typ" style="background-color: transparent; border: 0px; color: #2b91af; margin: 0px; padding: 0px; vertical-align: baseline;">HttpUtility</span><span class="pun" style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">.</span><span class="typ" style="background-color: transparent; border: 0px; color: #2b91af; margin: 0px; padding: 0px; vertical-align: baseline;">ParseQueryString</span><span class="pun" style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">(</span><span class="pln" style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">querystring</span><span class="pun" style="background-color: transparent; border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;">);</span></code></pre>
<pre class="lang-cs prettyprint prettyprinted" style="background-color: #eeeeee; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"><code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"><span class="pun" style="background-color: transparent; border: 0px; font-size: 14px; line-height: 18px; margin: 0px; padding: 0px; vertical-align: baseline;"><span style="font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;">http://localhost:8128/Action/ActionExecute/command=c:/notepad&.exe
Dostal jsem výsledek:
0) command=c:\notepad
1) null = .exe</span></span></code></pre>
<pre class="lang-cs prettyprint prettyprinted" style="background-color: #eeeeee; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"><code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"><span class="pun" style="background-color: transparent; border: 0px; font-size: 14px; line-height: 18px; margin: 0px; padding: 0px; vertical-align: baseline;"><span style="font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;">Jak z toho ven (sto hoven)?</span></span></code></pre>
</li>
</ol>
Nakonec jsem napsal dotaz na stackoverflow:<br />
<a href="http://stackoverflow.com/questions/15572682/how-to-correct-parse-query-string-in-c">Parse Query string</a><br />
<br />
Řešení je velmi jednoduché. Musíte dostat korektní QueryString, který má nahrazené řídící znaky escape sekvencí.Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-74804682329623103852013-03-18T15:05:00.001-07:002013-03-18T15:05:20.712-07:00Kroutím hlavou<div><p dir=ltr>string stanice="frekvence1";</p>
<p dir=ltr>Public string get()<br>
{<br>
string stanice="kiss";<br>
return stanice;<br>
}</p>
</div>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-10748424254041900662013-03-07T07:11:00.000-08:002013-03-07T07:11:08.048-08:00Window Manager<div class="separator" style="clear: both; text-align: left;">
Přemýšlím, jak do aplikačního frameworku MEF, Prism začlenit Windows manager</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://docs.google.com/drawings/d/14_2n7VU7Afd41hWqxTqqphyLq-q2-SiOmGVLr3_Mj_k/pub?w=960&h=720" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://docs.google.com/drawings/d/14_2n7VU7Afd41hWqxTqqphyLq-q2-SiOmGVLr3_Mj_k/pub?w=960&h=720" width="320" /></a></div>
<br />
Inspirace:<br />
<div>
http://www.codeproject.com/Articles/249261/How-To-Embed-An-Application-Into-a-Docking-Library</div>
<div>
<br /></div>
<div>
<br /></div>
Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-54796691420885578982012-11-23T05:15:00.001-08:002012-12-04T02:24:26.125-08:00WCF ROUTING<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBRJ1JESCd_btpt2A0eXlEjmig6RV8ct1__1idBrTcYd2Q58r6L8LCWuanULTcyvjmHu4UY7zBU7kZAr1Wk85ZJjvGhyphenhyphenW3Uq1IpjHuR-mD3rFqYn5DP9f8-RixdgYXAjpEBtKvBnJhSGE/s1600/wcf+routing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBRJ1JESCd_btpt2A0eXlEjmig6RV8ct1__1idBrTcYd2Q58r6L8LCWuanULTcyvjmHu4UY7zBU7kZAr1Wk85ZJjvGhyphenhyphenW3Uq1IpjHuR-mD3rFqYn5DP9f8-RixdgYXAjpEBtKvBnJhSGE/s320/wcf+routing.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
http://msdn.microsoft.com/en-us/library/ee517421.aspx</div>
<br />Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-169910101826983722012-03-16T07:22:00.001-07:002012-03-16T07:24:35.037-07:00Android - Kreslení bitmap do CanvasuPrvní tutoriál na téma AndroidMišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-40836428217477497372012-03-08T05:29:00.001-08:002012-03-08T06:06:09.500-08:00WCF - RESTFULL - service - webová službaDo našeho serveru budeme přidávat dolaší WCF službu. Tentokráte se bude jednat o služby přístupnou přes HTTP protokol. Jedná se o klasickou webovou službu.<br />
<br />
Podívejme se na příklad:<br />
Vytvoříme si nový ServiceContract.<br />
<div class="sh_result">
<pre>[ServiceContract]
<span class="net_key">public</span> <span class="net_key">interface</span> IEventService
{
[OperationContract]
[WebGet(UriTemplate = <span class="net_string">"EventInfo/{exe_name}"</span>, ResponseFormat = WebMessageFormat.Xml)]
EventInfo GetEventInfo(<span class="net_key">string</span> exe_name);
}</pre>
</div>
<span style="font-family: inherit;">Způsob volání přes protokol HTTP se konfiguruje pomocí atributu WebGet. Bude se jednat o volání přes HTTP příkaz GET. Kdybychom chtěli využít jiných HTTP příkazů, můžeme využít atributu WebInvoke pro jejich konfiguraci.</span>
<div class="sh_result">
<pre>[OperationContract]
[WebInvoke(Method = <span class="net_string">"PUT"</span>, UriTemplate = <span class="net_string">"/customer/{id}"</span>)]
<span class="net_key">public</span> <span class="net_key">void</span> PutCustomer(<span class="net_key">int</span> id, Customer customer)
{
}
[OperationContract]
[WebInvoke(Method = <span class="net_string">"DELETE"</span>, UriTemplate = <span class="net_string">"/customer/{id}"</span>)]
<span class="net_key">public</span> <span class="net_key">void</span> DeleteCustomer(<span class="net_key">int</span> id)
{
}</pre>
</div>
Podívejme zpět se na první příklad, kde funkce GetEventInfo vrací třídu EventInfo. Zajisté vás zajímá, v jakém formátu se vrátí odpověď od serveru. Formát si můžete přepnout buď přepínačem ResponseFormat = WebMessageFormat.Xml nebo přepínačem ResponseFormat = WebMessageFormat.Json. Zaměřme se na XML formát.
Mám jednoduchou třídu:
<div class="sh_result"><pre>[DataContract]
<span class="net_key">public</span> <span class="net_key">class</span> EventInfo
{
[DataMember]
<span class="net_key">public</span> <span class="net_key">string</span> Name
{
get;
set;
}
}</pre></div>
Server mi vrátí XML a názvy tagů jsou totožné z názvy tříd. Server vrátí výsledné XML jako:
<div class="sh_result"><pre><EventInfo>
<Name>AKCE</Name>
</EventInfo></pre></div>
To je dobré, ale často mohu potřebovat pojmenovat tagy nějakým vlastním jménem. Jakým způsobem mohu ovlivnit názvy tagů?
<div class="sh_result"><pre>[DataContract(Name=<span class="net_string">"MyEventInfo"</span>)]
<span class="net_key">public</span> <span class="net_key">class</span> EventInfo
{
[DataMember(Name=<span class="net_string">"Jmeno"</span>)]
<span class="net_key">public</span> <span class="net_key">string</span> Name
{
get;
set;
}
}</pre></div>
<br/>
Pokud do atributu DataContract přidáte parametr Name, dostane tag ve výstupním XML toto jméno. To samé se stane, když přidáte parametr Name do atributu DataMember.Ze serveru se mi vrátí XML:
<br />
<div class="sh_result"><pre><MyEventInfo xmlns=<span class="net_string">"http://schemas.datacontract.org/2004/07/WCF8bcPgServices"</span> xmlns:i=<span class="net_string">"http://www.w3.org/2001/XMLSchema-instance"</span>>
<Jmeno>AKCE</Jmeno>
</MyEventInfo></pre></div>
To je vše přátelé.Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-52473461224527495332012-02-24T04:49:00.003-08:002012-02-24T04:52:00.603-08:00WEB Request - GETPotřeboval jsem zavolat jednoduchou službu na webu, kde jsem přes URL předal parametry. K tomu mi postačí HTTP dotaz typu GET.<br />
<br />
<div class="sh_result"><pre>WebRequest request = WebRequest.Create(service + invoke);
request.Method = <span class="net_string">"GET"</span>;
<span class="net_key">using</span> (WebResponse response = request.GetResponse())
{
<span class="net_key">using</span> (Stream stream = response.GetResponseStream())
{
XmlTextReader reader = <span class="net_key">new</span> XmlTextReader(stream);
}
}</pre></div><br />
URL jsem si rozděli na URL služby - service a parametry volání - invoke. Dejte pozor na nepovolené znaky. Před odeslání prožeňte parametry url encoderem, který vám nahradí nepovolené znaky.<br />
<br />
<div class="sh_result">System.Web.HttpUtility.UrlEncode(url_encode);<br />
</div><br />
Na straně serveru si nezapomeňte parametry dekódovat zpět.<br />
<br />
<div class="sh_result">System.Web.HttpUtility.UrlDecode(pars);<br />
</div>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-16338539648108497352012-01-26T04:41:00.001-08:002012-01-26T04:54:33.045-08:00WPF DataGrid - scrollovaní na poziciVe WPF DataGridu jsem potřeboval zobrazit jednu položku která je kdekoliv v tabulce. Tabulka má hodně řádků a já chci do zobrazení dostat nějaký řádek, který není vidět.<br />
<br />
Je to velice jednoduché:<br />
<br />
<div class="sh_result">datagrid.ScrollIntoView(next);<br />
</div><br />
Položka se zviditelní, ale bohužel se může objevit kdekoliv v pohledu. Může se zobrazit na první zobrazené pozici nebo naopak na poslední pozici. To se děje podle toho, jestli scrollujete nahoru nebo dolu. Je to užitečná funkce, ale já jsem dostal v práci zadání, že zobrazená položka musí být na první zobrazené pozici. Jak na to? Dlouho jsem pátral po tom, jakým způsobem se mám napíchnout na scrollbar uvnitř gridu, a také jsem si myslil, že to ani není možné. Dnes jsem našel kód, který vyhledá srollbary přes vizuální strom. Já jsem hledal chybně scrollbary, ale měl jsem hledat tzv. ScrollViewer. <br />
<br />
Příklad funkce, která vrátí ScrollViewer:<br />
<div class="sh_result"><pre><span class="net_key">private</span> <span class="net_key">static</span> ScrollViewer GetScrollbar(DependencyObject dep)
{
<span class="net_key">for</span> (<span class="net_key">int</span> i = 0; i < VisualTreeHelper.GetChildrenCount(dep); i++)
{
var child = VisualTreeHelper.GetChild(dep, i);
<span class="net_key">if</span> (child != <span class="net_key">null</span> && child <span class="net_key">is</span> ScrollViewer)
<span class="net_key">return</span> child <span class="net_key">as</span> ScrollViewer;
<span class="net_key">else</span>
{
ScrollViewer sub = GetScrollbar(child);
<span class="net_key">if</span> (sub != <span class="net_key">null</span>)
<span class="net_key">return</span> sub;
}
}
<span class="net_key">return</span> <span class="net_key">null</span>;
}</pre></div>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-76187787304377287142011-12-02T02:36:00.000-08:002011-12-02T02:36:14.654-08:00WPF - Drag and DropDnes jsem začal do WPF aplikace implementovat základní dovednost ve většině aplikací - Drag and Drop. Pojďme se podívat, jak Drag and Drop ve WPF funguje.Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-10990332664610403172011-12-01T04:37:00.001-08:002011-12-01T07:20:31.443-08:00Každe okno aplikace ve vlastním vlákně - pokračováníJak jsem zmínil nedávno v <a href="http://misak81.blogspot.com/2011/11/sta-single-threaded-apartments-mta.html">příspěvku</a>, potřebuji do své poslední aplikace, aby každý modul a hlavně také jeho okno běžel v samostatném vlákně.<br />
<br />
Požadavky:<br />
- Když v jednom okně provádím náročnější operaci, nesmí vytuhnout ostatní okna.<br />
- Když dojede k pádu v jednom modulu tak potřebuji, aby ostatní moduly fungovali dál.<br />
<br />
Jak jsem psal v předešlém článku, požadovaného výsledku dosáhneme vytvořením STA vlákna pro každé okno.<br />
<br />
Když pak spustíme aplikaci, zjistíme, že každé okno funguje opravdu v nezávislém vlákně. Brzo si všimnete velmi nepříjemné vlastnosti takové aplikace - okna jsou opravdu na sobě nezávislá a fungují jako samostatné aplikace uvnitř vaší aplikace. Důsledkem toho vám program přestane správně fungovat při minimalizaci a opětovné maximalizaci. Po opětovné maximalizaci se vám zobrazí pouze okno hlavního vlákna. Ale kde jsou ty ostatní okna?<br />
<br />
První myšlenka, která mě napadla bylo, nastavení vlastnosti Window.Owner. Tuto vlastnost bohužel z jiného vlákna nenastavíte, protože tímto vyvoláte kód v hlavním vlákně. <br />
<br />
<div class="sh_result"><pre>_window.Owner = Application.Current.MainWindow;</pre></div><br />
Dojde k výjímce:<br />
The calling thread cannot access this object because a different thread owns it.<br />
<br />
Dlouho jsem procházel nejrůznější fóra, až jsem objevil konstrukci, která tuto WPF chybku obejde.<br />
<br />
<div class="sh_result"><pre><span class="net_key">string</span> strFriendlyName = AppDomain.CurrentDomain.FriendlyName;
Process[] pro = Process.GetProcessesByName(strFriendlyName.Substring(0, strFriendlyName.LastIndexOf(<span class="net_string">'.'</span>)));
<span class="net_key">typeof</span>(System.Windows.Window).InvokeMember(<span class="net_string">"_ownerHandle"</span>,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetField,
<span class="net_key">null</span>, _window, <span class="net_key">new</span> <span class="net_key">object</span>[] { pro[0].MainWindowHandle });
_window.Closed += <span class="net_key">new</span> EventHandler(WindowClosed);
_window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
_window.ShowDialog();
//System.Windows.Threading.Dispatcher.Run();</pre></div><br />
A můžeme si oddechnout, opravdu to funguje.<br />
<br />
<a href="http://eprystupa.wordpress.com/2008/07/31/running-multiple-wpf-applications-in-the-same-process-using-appdomains/">Odkaz na článek</a>Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com1tag:blogger.com,1999:blog-5833625534508328054.post-15580102126685668252011-11-28T21:08:00.001-08:002011-11-30T01:57:59.238-08:00Složitost O(n)Pokud softwarový designer navrhuje celý aplikační systém a vytváří vlastnosti tohoto systému jen z případu užití - Use cases, očekává od systému něco co navrhl. Dle mého názoru by si ale měl i designér, který není programátorem měl uvědomit, že jeho návrhy mohou významně ovlivnit většinu algoritmů v systému. Výsledkem čehož je pomalejší provádění všech algoritmů a větší čas potřebný ke zpracování. Vezměme si například geniální myšlenku využívání dynamických datových struktur namísto statických. A k tomu si přidejme navíc využívání multihodnot namísto jednohodnotových položek.<br />
<br />
Poznámka:<br />
Příkladem multihodnoty z běžného života je telefon. Mohu mít více telefonních čísel, proto se hodnota telefon v dynamické struktuře vyskytuje vícekrát.<br />
<br />
Podívejme se na to, jak se změní v celém systému složitosti algorimu po zavedení dynamických datových struktur. Pro zjednodušení neuvažujeme že hodnotou u dynamické datové struktury může být jakýkoliv datový typ, vliv variantního typu a nutnosti přetypování je zanedbán.<br />
<br />
<b>A . Máme statickou datovou strukturu</b><br />
LibraryElement<br />
• elementID<br />
• Artist[50]<br />
• Title[50]<br />
<br />
<b>B. Máme dynamickou datovou strukturu</b><br />
LibraryElement – je pole<br />
Item[1] – elementID<br />
Item[2] – Artist <br />
Item[3] – Artist<br />
.<br />
.<br />
.<br />
Item[10] – Title <br />
Zpracování jedno údaje ve struktuře má složitost O(1).<br />
Zpracování jedné informace<br />
<b>Příklad 1. Abych zobrazil jednu položku např. Artist potřebuji složitost</b><br />
M – počet atributů nebo chceteli počet položek ve struktůře<br />
A. O(1)<br />
B. O(2) – obecně O(M)<br />
<br />
Zpracování pole informací – zpracování celé knihovny<br />
<b>Příklad 2. Zobrazení knihovny o N prvcích</b><br />
A – počet zobrazovaných atributů<br />
A. O(N*A)<br />
B. O(N*A*M)<br />
<b>Příklad 3.Třídění informací – quicksort O(N log2 N)</b><br />
A. O(N log2 N)<br />
B. O((N*M) log2 (N *M))<br />
<b>Příklad 4. Přenos informací – složitost potřebná k serializaci a deserializaci</b><br />
<br />
A. O(N) – u statické struktůry tedy mohu mluvit jednoduše o přenosu X KB/s<br />
Vím, že chci úřenést (2b + 50+50) * N<br />
B. O(N*M) - u statické struktury není správné mluvit o X KB/s … protože proces serializace a deserializace má mnohem větší složitostMišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0tag:blogger.com,1999:blog-5833625534508328054.post-35416581344816219712011-11-28T02:29:00.000-08:002011-11-29T01:49:19.226-08:00WPF - Každé okno v aplikaci má vlastní vlákno - STA = Single threaded apartments, MTA = Multi-Threaded ApartmentsVe chvíli, kdy založíte nový projekt ve Visual Studio, vygeneruje se vám základní kostra aplikace. Která podle typu projektu WinForm nebo WPF vytvoří vstupní bod aplikace.<br />
<br />
WinForm - funkce main<br />
WPF - funkce main je skrytá, ale je možné ji přetížit a napsat si vlastní<br />
<br />
Funkce main je vstupním bodem aplikace a je prováděna v hlavním vlákně aplikace (MainThread). Toto vlákno je nastaveno jako STA - Single thread apartments. Každé okno, které vytvoříme v aplikaci běží v rámci toho STA (kontejnéru na vlákna). Pokud budeme chtít vytvořit jiné vlákno, které bude provádět nějakou činnost, tak toto vlákno má nastaven apartments na MTA (multi-thread apartments). Data z tohoto vlákna můžeme synchronizovat do okna aplikace pomocí dispečeru.<br />
<br />
<div class="sh_result"><pre>myThread = <span class="net_key">new</span> Thread(<span class="net_key">new</span> ThreadStart(Execute));
myThread.Start();</pre></div><br />
V tomto vlákně máme nějaká omezení. Nemůžeme v něm vytvářet okna, ovládací prvky atd. Pokud chcete vytvořit nové okno v rámci jiného vlákna než je hlavní vlákno aplikace, vytvořte nové vlákno, ale nastavte mu apartments na STA. <br />
<br />
<div class="sh_result"><pre>myThread = <span class="net_key">new</span> Thread(<span class="net_key">new</span> ThreadStart(Execute));
myThread.Name = <span class="net_string">"Thread"</span>;
myThread.SetApartmentState(ApartmentState.STA);
myThread.IsBackground = <span class="net_key">true</span>;
myThread.Start();</pre></div><br />
Nyní máme vytvořeno okno, ve kterém můžeme vytvořit nezávislé okno, ale aby okno fungovalo, musíme v rámci tohoto vlákna spustit dispečeram který se bude starat o případné synchronizace s jinými vlákny. Bez dispečera nebude okno fungovat.<br />
<br />
<div class="sh_result"><pre>oid Execute()
{
MyWindow win = <span class="net_key">new</span> MyWindow();
win.Show();
System.Windows.Threading.Dispatcher.Run();
}</pre></div><br />
Nezávislé okno máme hotovo.<br />
<br />
<b>Závěr</b><br />
Hledal jsem příčinu, proč jsou takto pod .NETem vlákna řešena. Toto řešení se mi zdálo zbytečně komplikované. Ve většině článků bylo odůvodnění, že je to z důvodů zpětné kompatibility s COM objekty. Do hlubšího zkoumání jsem se už nepouštěl!Mišákhttp://www.blogger.com/profile/05112092005814335407noreply@blogger.com0