středa 7. května 2014

WPF - 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:
FocusVisualStyle="{StaticResource MyFocusVisualStyle}"

 A příklad:
<SolidColorBrush x:Key="SelectBrushAlpha" Color="#99288AF7"/>    
    <Style x:Key="MyFocusVisualStyle">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Fill="{StaticResource SelectBrushAlpha}" SnapsToDevicePixels="true" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

WPF - 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.




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.

Celkem zajímavá je ale možnost ale ovlivnit možnost navigace klávesnící ItemsControl, připadně v jiném kontejnéru.

Navigaci klávesnící ovlivním snadno přes třídu - KeyboardNavigation.
V MSDN si o tom můžete přečíst ZDE.

Navigaci přes Tabulátor ovlivníte  - KeyboardNavigation.TabNavigation
Směrovou navigaci přes šipky ovlivníte  - KeyboardNavigation.DirectionalNavigation

A možnosti jsou následující: Contained, Continue, Cycle, Local, None, Once

Nejlépe je si chování vyzkoušet na příkladu:

<GroupBox Header="Check Boxes" KeyboardNavigation.TabNavigation="Once"
                  Height="126" HorizontalAlignment="Left" 
                  VerticalAlignment="Top" Width="200">
            <StackPanel Margin="8">
                <CheckBox Content="Check Box 1"/>
                <CheckBox Content="Check Box 2"/>
                <CheckBox Content="Check Box 3"/>
                <CheckBox Content="Check Box 4"/>
                <CheckBox Content="Check Box 5"/>
            </StackPanel>
        </GroupBox>
        
        <GroupBox x:Name="gbRadio" Header="Radio Buttons" Height="126" VerticalAlignment="Top" Margin="206,0,107,0">
            <StackPanel Margin="8">
                <RadioButton x:Name="radio1" Content="Radio Button 1"/>
                <RadioButton Content="Radio Button 2"/>
                <RadioButton Content="Radio Button 3"/>
                <RadioButton Content="Radio Button 4"/>
                <RadioButton Content="Radio Button 5"/>
            </StackPanel>
        </GroupBox>

A přitom taková blbost, ale potěší :).

pondělí 17. března 2014

Můj první CmdLet do Powershellu.

Můj první CmdLet do Powershellu

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.

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.

Co kdyby pán démonů místo našich jobů spouštěl powershell scripty?
Co kdybych začal jednoduše tím, že si napíši svůj první CmdLet.

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.

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ší.

[RunInstaller(true)]
    public class CmdLetSnapIn : PSSnapIn
    {
        public override string Name
        {
            get { return "CmdLet"; }
        }
        public override string Vendor
        {
            get { return ""; }
        }
        public override string VendorResource
        {
            get { return "CmdLet,"; }
        }
        public override string Description
        {
            get { return "Registers the CmdLets and Providers in this assembly"; }
        }
        public override string DescriptionResource
        {
            get { return "CmdLet,Registers the CmdLets and Providers in this assembly"; }
        }
    }

Třída PSCmdlet, je třída CmdLetu. Třída slouží k vykonání CmdLetu.
[Cmdlet(VerbsCommon.Get, "CmdTest", SupportsShouldProcess = true)]
    public class CmdTest : PSCmdlet
    {

        #region Parameters
        /*
        [Parameter(Position = 0,
            Mandatory = false,
            ValueFromPipelineByPropertyName = true,
            HelpMessage = "Help Text")]
        [ValidateNotNullOrEmpty]
        public string Name
        {
            
        }
        */
        #endregion

        protected override void ProcessRecord()
        {
            try
            {
                WriteObject(System.Diagnostics.Process.GetProcesses(), true);
            }
            catch (Exception)
            {
            }
        }
    }

Třída má definovaný důležitý attribut Cmdlet, 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")].

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.


  • SnapIn registrujeme pomocí .NET utiliti InstallUtil jmenosnapinu (cesta dll)
  • Registrované přílepky si vylistujeme: Get-PSSnapIn -registered - tady se objeví v seznamu CmdLet (jméno z třídy PSSnapIn).
  • SnapIn přidámě pomocí Add-PSSnapIn CmdLet
  • CmdLet zavoláme pomocí Get-CmdTest (!!!Název definovaný attributem Cmdlet!!!)



pondělí 13. ledna 2014

.NET Memory leaks

Problém: Zdravím, máme celkem rozsáhlý projekt v .NET, který také volá nativní dll. Aplikaci neustále narůstá paměť.

úterý 31. prosince 2013

Nový rok 2014

Všechno nejlepší do Nového roku 2014, hodně čistého a znovupoužitého kódu, který přežije nejeden projekt.

A hlavně zdravíčko a dobré přátele.