/// <summary> /// Calcul de la hauteur en pixels d'un élément de la liste /// </summary> /// <param name="e">descripteur issue d'un événement MeasureItem de l'hôte</param> /// <param name="item">référence non null sur l'item à peindre</param> public void MeasureRichItem( MeasureItemEventArgs e, RichItem item ) { // déterminer la font associée à l'item Font itemFont = item.Font; if ( itemFont == null ) itemFont = host.Font; // dimensions requises pour le texte Size textMetrics = TextRenderer.MeasureText( item.Text, itemFont ); e.ItemHeight = textMetrics.Height; e.ItemWidth = textMetrics.Width; // forcer les chaînes vides à être visibles if ( e.ItemHeight == 0 ) e.ItemHeight = (int) System.Math.Ceiling( itemFont.GetHeight( e.Graphics ) ); // assurer l'espce vertical entre les items en ce qui concerne le texte e.ItemHeight += textVSpace; // considérer l'image si nécessaire Image itemImage = host.ImageShow ? item.Image : null; if (itemImage == null) return ; // éviter de stretcher les images pour un petit nombre de pixels int imageMissing = itemImage.Height + imageVSpace - e.ItemHeight; if ( 0 < imageMissing && imageMissing < imageVStretchMin ) e.ItemHeight = itemImage.Height + imageVSpace; }
/// <summary> /// Peinture d'un élément de la liste déroulante /// </summary> /// <param name="e">descripteur issu d'un événement DrawItem de l'hôte</param> /// <param name="item">référence non null sur l'item à peindre</param> public void DrawRichItem( DrawItemEventArgs e, RichItem item ) { // peinture du fond de l'item ou de l'indication de sélection e.DrawBackground(); // indentation du texte int textIndent = item.IndentLevel * host.IndentWidth; // espace à réserver pour l'image int imageWidth = 0; int imageOffset = 0; if ( host.ImageShow ) { imageWidth = e.Bounds.Height; imageOffset = 2; } // déterminer la font associée à l'item Font itemFont = item.Font; if ( itemFont == null ) itemFont = host.Font; // déterminer la hauteur du texte en pixels float textHeight = host.DrawMode == DrawMode.OwnerDrawFixed ? host.Font.GetHeight( e.Graphics) : itemFont.GetHeight( e.Graphics ); textHeight = (float) Math.Floor( textHeight - 1 ); // déterminer la font d'affichage // todo (RichListPainter) : optimiser l'obtention de la font Font textFont = new Font( itemFont.FontFamily, textHeight, itemFont.Style, GraphicsUnit.Pixel ); // déterminer le calage du texte int textTop = textHeight > e.Bounds.Height ? 0 : (int) (e.Bounds.Height - textHeight) / 2; int textWidth = e.Bounds.Width - imageWidth - textIndent - imageOffset; int textLeft = host.IsRightToLeft ? e.Bounds.X - imageOffset : e.Bounds.X + imageWidth + textIndent + imageOffset; Rectangle textRect = new Rectangle( textLeft, e.Bounds.Y, textWidth, e.Bounds.Height ); TextFormatFlags textFlags = host.IsRightToLeft ? TextFormatFlags.Right : TextFormatFlags.Left; // peindre le texte TextRenderer.DrawText( e.Graphics, item.Text, textFont, textRect, item.ForeColor, textFlags ); // partie image Image itemImage = host.ImageShow ? item.Image : null; if ( itemImage == null ) return; // inverser l'image si orientation droite à gauche // utiliser un clone de l'image pour éviter les effets de bord //if ( host.IsRightToLeft ) { // itemImage = itemImage.Clone() as Image; // itemImage.RotateFlip( RotateFlipType.RotateNoneFlipX ); //} // éviter de stretcher les images pour un petit nombre de pixels int imageRemaining = e.Bounds.Height - imageVSpace - itemImage.Height; int imageSize = imageRemaining < 0 || imageVStretchMin < imageRemaining ? e.Bounds.Height - imageVSpace : itemImage.Height; // ajuster le calage de l'image int imageLeft = host.IsRightToLeft ? e.Bounds.Width - (imageOffset + itemImage.Width + textIndent) : imageOffset + textIndent; int imageTop = imageSize >= e.Bounds.Height ? 0 : (e.Bounds.Height - imageSize) / 2; Rectangle imageRect = new Rectangle( e.Bounds.X + imageLeft, e.Bounds.Y + imageTop, imageSize, imageSize ); // peindre l'image e.Graphics.DrawImage( itemImage, imageRect ); }
private void DoWireItemOn( RichItem item ) { if ( item == null || item.Owner == this ) return; DoWireItemOff( item ); item.InternalWireToOwner( this ); }
void IRichControlHost.OnItemChanged( RichItem item ) { if ( item == null ) return; int index = Items.IndexOf( item ); if ( index != -1 ) RefreshItem( index ); }
/// <summary> /// Ajoute une collection d'items à la fin de la collection /// </summary> /// <param name="items">tableau d'items à ajouter</param> public void AddRange( RichItem[] items ) { // <wao code.&body RichItemCollection_abrégé.+body> if ( items == null ) return; host.BeginUpdate(); try { for ( int ix = 0 ; ix < items.Length ; ix++ ) Add( items[ ix ] ); } finally { host.EndUpdate(); } }
// // Service // private void DoWireItemOff( RichItem item ) { IRichCollectionOwner itemOwner = item == null ? null : item.Owner; if ( itemOwner == null ) return; item.InternalWireToOwner( null ); if (itemOwner != this) itemOwner.Remove( item ); }
/// <summary> /// Ajoute un item à la fin de la collection. /// </summary> /// <param name="item">référence sur l'item à ajouter</param> /// <returns>l'index d'adjonction</returns> public int Add( RichItem item ) { // <wao code.&body RichItemCollection_abrégé.+body> if ( item == null ) throw new ArgumentNullException( "item", "Méthode Add" ); DoWireItemOn( item ); return host.Items.Add( item ); }
/// <summary> /// Insère un item à une position donnée. /// </summary> /// <param name="index">index d'insertion</param> /// <param name="item">référence sur l'item à ajouter</param> public void Insert( int index, RichItem item ) { // <wao code.&body RichItemCollection_abrégé.+body> if ( item == null ) throw new ArgumentNullException( "item", "Méthode Insert" ); if ( index < 0 || Count < index ) throw new ArgumentOutOfRangeException( "index", "méthode RichItemCollection.Insert" ); DoWireItemOn( item ); host.Items.Insert( index, item ); }
/// <summary> /// Retire un item de la collection /// </summary> /// <param name="item">référence sur l'item à retirer</param> public void Remove( RichItem item ) { // <wao code.&body RichItemCollection_abrégé.+body> DoWireItemOff( item ); host.Items.Remove( item ); }
void IRichCollectionOwner.OnItemChanged( RichItem item ) { host.OnItemChanged( item ); }
//得到所有富文本的索引 List <int> GetAllRichIndex() { if (string.IsNullOrWhiteSpace(m_text.text)) { return(null); } string str = m_text.text; Dictionary <int, RichItem> map = new Dictionary <int, RichItem> (); Stack <int> stack = new Stack <int> (); for (int i = 0; i < str.Length; i++) { if (str[i] == '<') { RichItem b = new RichItem(); b.start = i; map.Add(i, b); stack.Push(i); } else if (str[i] == '>' && stack.Count > 0) { int index = stack.Pop(); RichItem b; if (map.TryGetValue(index, out b)) { b.end = i; b.isFinish = true; map[index] = b; } } } List <int> deleteIndexs = new List <int> (); var enumerator = map.GetEnumerator(); while (enumerator.MoveNext()) { RichItem b = enumerator.Current.Value; if (!b.isFinish) { continue; } int currentIndex = b.start; while (currentIndex <= b.end) { if (!deleteIndexs.Contains(currentIndex)) { deleteIndexs.Add(currentIndex); } currentIndex++; } } return(deleteIndexs); }