Avatar billede brian0905 Nybegynder
17. januar 2007 - 15:00 Der er 3 kommentarer og
1 løsning

Problem med at tegne

Hejsa,

Jeg er ved at overstyre tegningen af subitems i et listview. Jeg vil gerne gøre således at jeg kan vælge farven på en del af strengen i midten. (det er til et søgeprogram, den søger filer igennem og tegner så 3 tekst strenge: 1 - den der kommer indtil den fundne tekst, 2 - selve matchet (den fundne tekst), 3 - det der kommer efter den fundne tekst. Mit problem er at jeg får nogle store mellemrum hver gang jeg skriver noget nyt tekst, det er somom den tegner ekstra pixels, her er min kode:

private void resultListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) {
      if (e.ColumnIndex == 1) {
        ItemClass itemClass = (ItemClass)e.Item.Tag;
        string text = e.SubItem.Text;
        string match = itemClass.Match;
        int start = text.IndexOf(match);
        int end = match.Length;
        //SizeF spaceSize = e.Graphics.MeasureString(" ", this.Font);
        e.Graphics.DrawString(text.Substring(0, start), e.Item.Font, Brushes.Black, e.Bounds);
        SizeF textSize = e.Graphics.MeasureString(text.Substring(0, start), e.Item.Font);
        e.Graphics.DrawString(match, e.Item.Font, Brushes.Green, new RectangleF(e.Bounds.X + textSize.Width, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
        SizeF matchSize = e.Graphics.MeasureString(match, e.Item.Font);
        e.Graphics.DrawString(text.Substring(start + end, text.Length - (start + end)), e.Item.Font, Brushes.Black, new RectangleF((e.Bounds.X + textSize.Width) + matchSize.Width, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
        //e.Graphics.DrawString(itemClass.Match, this.Font, Brushes.Black, e.Bounds);
      } else {
        e.DrawText();
      }
     
    }

Koden bevirker at en linie kommer til at se således ud (tillempet):

"Dette er teksten før matchen    match    her er teksten efter"

Det vil sige at der er forholdsvis mere plads før og efter min kode der skriver mit match. Nogle løsninger?
Avatar billede clausc Nybegynder
17. januar 2007 - 15:29 #1
Smid en StringFormat med i kaldet.

Jeg har haft bedre resultater med en GenericTypographic. Alternativt kan du justere Trimming på StringFormat.

Begge klasser er beskrevet i SDK'et
Avatar billede brian0905 Nybegynder
18. januar 2007 - 09:14 #2
Hmm... det virkede ikke helt, har forsøgt med alle formaterne i StringFormat, den vil stadig ikke. Det er som om den "måler" for langt hver gang den måler, se dette screenshot (de røde kasser er størrelsen på min MeasureString: www.vikingworks.dk/filegrep.jpg
Avatar billede brian0905 Nybegynder
18. januar 2007 - 15:16 #3
Fandt selv løsningen, der skal bruges MeasureCharacterRanges, jeg paster lige koden, der tager udgangspunkt i  ownerdraw på et listview item, og tegner kun matches fra et RegExp:

private List<StringPart> GetAllMatchLocations(Match matches) {
      List<StringPart> result = new List<StringPart>();
      foreach (Group group in matches.Groups) {
        StringPart part = new StringPart();
        part.StartPos = group.Index;
        part.Length = group.Length;
        result.Add(part);
      }
      return result;
    }

    private void resultListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) {
      if (e.ColumnIndex == 1) {
        ItemClass itemClass = (ItemClass)e.Item.Tag;
        string text = e.SubItem.Text;
        string match = itemClass.Match;
        Match regexmatches = itemClass.RegularMatchCollection;
        List<StringPart> matches = GetAllMatchLocations(regexmatches);
        CharacterRange[] ranges = new CharacterRange[matches.Count];
        for (int i=0;i<matches.Count;i++) {
          StringPart part=matches[i];
          ranges[i]= new CharacterRange(part.StartPos, part.Length);         
        }

        StringFormat format = new StringFormat();
        format.SetMeasurableCharacterRanges(ranges);

        Region[] regions = e.Graphics.MeasureCharacterRanges(text, e.Item.Font, e.Bounds, format);
        foreach (Region region in regions) {
          e.Graphics.SetClip(region, System.Drawing.Drawing2D.CombineMode.Exclude);
        }
        e.Graphics.DrawString(text, e.Item.Font, Brushes.Black, e.Bounds);

        e.Graphics.ResetClip();
        e.Graphics.SetClip(Rectangle.Empty);

        foreach (Region region in regions) {
          e.Graphics.SetClip(region, System.Drawing.Drawing2D.CombineMode.Union);         
        }
        e.Graphics.DrawString(text, e.Item.Font, Brushes.Red, e.Bounds);
      } else {
        e.DrawText();
      }
     
    }
Avatar billede brian0905 Nybegynder
18. januar 2007 - 15:17 #4
Lukker, kan ikke garantere at linket til billedet holder :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester