none
Pás karet ve Wordu 2007 a aktuální pozice v dokumentu

    Dotaz

  • Používám Visual Studio for Office při vývoji aplikace pro Word (typu Word 2007 Template), a protože jsem žádné odpovídající fórum nenašel, tak snad se to sem hodí.

    Ve Wordu 2007 nedokážu přimět pás karet (ribbon), aby reagoval na aktuální pozici kurzoru v dokumentu. Požadavek je následující:

    Existuje nabídka (menu) se seznamem stylů; když na nabídku kliknu, program zjistí, jaký znakový nebo odstavcový styl se nachází na aktuální pozici kurzoru, a odpovídající styl v seznamu označí (plus kliknutím na jinou položku nastaví odpovídající styl pro aktuální výběr v dokumentu).

    Ve Wordu 2003 to bylo možné provést pomocí VBA díky události PopUp, která se spouštěla při kliknutí na nabídku. Viz např. tento kód:

    Code Snippet

    Public Sub NabidkaStylu_PopUp(Optional sPopUp As String)
    'sPopUp = identifikátor nabídky (odstavcových nebo znakových stylů)
    Dim sAktualniStyl As String 'název aktuálního stylu

    Dim c As CommandBarControl
    Dim p As CommandBarPopup

       If Len(sPopUp) = 0 Then sPopUp = ZjistitParametr 'pomocná procedura pro zjištění parametru aktivního prvku
       If Len(sPopUp) = 0 Then Exit Sub
      
      
       Set p = CommandBars.ActionControl 'prvek, který vyvolal tuto rutinu
       If p Is Nothing Then Exit Sub
      
       Select Case sPopUp
          Case cspupOdstavce 'vyvolala se nabídka odstavcových stylů
             sAktualniStyl = ZjistiAktualniStyl(wdStyleTypeParagraph)
             'nyní se prochází jednotlivé položky v nabídce stylů
             For Each c In p.Controls
                c.Visible = True
                'pokud je název stylu stejný jako parametr položky z nabídky, označí se položka jako vybraná, jinak jako nevybraná
                c.State = IIf(c.Parameter = sAktualniStyl, msoButtonDown, msoButtonUp)
             Next c
          Case cspupZnaky 'vyvolala se nabídka znakových stylů
             sAktualniStyl = ZjistiAktualniStyl(wdStyleTypeCharacter)
             'nyní se prochází jednotlivé položky v nabídce stylů
             For Each c In p.Controls
                c.Visible = True
                'pokud je název stylu stejný jako parametr položky z nabídky, označí se položka jako vybraná, jinak jako nevybraná

                c.State = IIf(c.Parameter = sAktualniStyl, msoButtonDown, msoButtonUp)
             Next c
       End Select
    End Sub



    Pro označení (zrušení) položky v nabídce ve Wordu 2007 používám prvky toggleButton a jejich událost GetPressed. Největší problém je ten, že nabídka v rámci pásu karet se načítá jenom jednou, a to při prvním otevření menu. Pokud chci, aby se položky v nabídce zobrazovaly jinak (aby se znovu spustila událost getPressed), musím celý pás zneplatnit (voláním

    Code Snippet

    this.ribbon.Invalidate();


    ). Jen tak mimochodem: pokoušel jsem se volat také funkci

    Code Snippet

    this.ribbon.InvalidateControl("grpStylyMnuOdstavce");


    v domnění, že stačí zneplatnit dané menu, aby se znovu generovala událost GetPressed, ale nepomohlo to; nejspíš je potřeba zneplatnit konkrétní vnořené prvky, nikoli jenom prvek nadřazený.

    Řešení problému je tedy nasnadě: zneplatnit pás karet, kdykoli se změní pozice kurzoru. Bohužel to nedokážu udělat automaticky. Jednak jsem nepřišel na to, jak z události ThisDocument_SelectionChange zavolat funkci Invalidate() prvku Ribbon, který byl vytvořen na základě souboru XML, jednak událost SelectionChange týká pouze změny pozice kurzoru kliknutím myši nebo pohybem kurzorovými klávesami a nespustí se, když například uživatel změní styl z vestavěné wordovské nabídky stylů a napíše nějaký text.

    Pokud někoho napadá, jak zajistit, aby se při rozevření menu zobrazoval aktuální stav, který odpovídá aktuální pozici kurzoru, uvítám jeho radu.
    14. června 2008 13:11

Odpovědi

Všechny reakce

  • Zatím jsem vyřešil první problém: jak z události ThisDocument_SelectionChange zavolat funkci Invalidate() prvku Ribbon, který byl vytvořen na základě souboru XML.

    Postup je následující: v rámci třídy Ribbon (která obsahuje můj pás karet) jsem definoval veřejnou funkci, která volá zneplatnění interního objektu ribbon.

    Code Snippet
    public void Invalidate() {
     this.ribbon.Invalidate();
    }

    Do třídy ThisDocument je potřeba doplnit následující části kódu:

    Code Snippet

    private Ribbon mirRibbon;


    protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
    { mirRibbon = new Ribbon();
      return mirRibbon;
    }


    private void ThisDocument_SelectionChange(object sender, Microsoft.Office.Tools.Word.SelectionEventArgs e)
    { mirRibbon.Invalidate(); }


    Je potřeba uchovat odkaz na vytvořený objekt třídy Ribbon (původní kód funkce CreateRibbonExtensibilityObject() doporučovaný návrhářem ribbonů z Visual Studia obsahuje jenom řádek return = new Ribbon();) a při události SelectionChange volat vlastní funkci pro zneplatnění pásu karet.
    14. června 2008 13:34
  • Podivejte se na WebCasty a prezentace venovane vyvoji aplikaci pro Office pomoci VSTO. V techto prezentacich jsou mimo jine i informace jak vyvijet vlastni RibbonX prvky.

     

    Webcasty se nachazeji zde: (doporucuji jak VSTO 2008, tak i VSTO 2005): http://www.microsoft.com/cze/msdn/webcasts/default.mspx

     

    Prezentace: http://www.microsoft.com/cze/events/archive/2007/20071113_devdnet/default.mspx

     

     

     

     

    17. června 2008 7:59