CheckedListBoxのItemそれぞれに状態を示すbool型のパラメータを持たせたい


現在，VisualStudioC#のフォームアプリケーションで，CheckedListBoxを使用してToDoリストを制作しています．

ListBoxの機能に加えて各アイテムがチェックされているかどうかという状態を保存できますが，  
それに加えて各アイテムに対し重要であるかどうかという状態を保存できるようにしたいと考えています．  
CheckedListBoxを継承したカスタムコントロールを作成して，これを実現することは可能でしょうか．この重要かどうかを変更できるメソッドをフォームから呼び出せるようにし，最終的にはOnDrawItemをオーバーライドし，重要な要素のForeColorを変えるということを考えています．

できれば具体的な実装方法を教えていただきたいです．  
よろしくお願いします．




データバインディングで解決できます。  
Infoクラスは、1つの項目の状態を保持するためのクラスとなります。

CheckedListBoxクラスを継承したCheckedListBoxExを使用し、  
OnDrawItemメソッドをオーバーライドし、InfoクラスのImportantプロパティで見た目を変えています。

ObservableCollectionを使用していますがListでも、この場合は、構いません。

  * フォームでは、データバインディングに限界があります、できればWPFに移行を推奨します。 
  * 下記のコードは、参考に程度にしてください。適当実装なため…

* * *
[code]

    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1 {
        public partial class Form1 : Form {
            private readonly BindingSource binder = new BindingSource();
            private readonly ObservableCollection<Info> items = new ObservableCollection<Info>() {
                new Info() {
                    Checked = true,
                    Name = "hoge"
                }
            };
            public Form1() {
                InitializeComponent();
            }
    
            private void Form1_Load( object sender , EventArgs e ) {
                this.binder.DataSource = items;
                this.checkedListBox1.DataSource = this.binder;
            }
    
            private void button1_Click( object sender , EventArgs e ) {
                this.items[0].Important = !this.items[0].Important;
    
                this.binder.Add( new Info() {
                    Checked = true ,
                    Important = true ,
                    Name = "hoge"
                } );
            }
        }
    
        public sealed class Info : INotifyPropertyChanged {
            public bool Checked {
                get {
                    return this._Checked;
                }
                set {
                    if( this._Checked == value )
                        return;
                    this._Checked = value;
                    this.OnPropertyChanged( "Checked" );
                }
            }
            private bool _Checked;
    
            public string Name {
                get {
                    return this._Name;
                }
                set {
                    if( this._Name == value )
                        return;
                    this._Name = value;
                    this.OnPropertyChanged( "Name" );
                }
            }
            private string _Name;
    
            public bool Important {
                get {
                    return this._Important;
                }
                set {
                    if( this._Important == value )
                        return;
                    this._Important = value;
                    this.OnPropertyChanged( "Important" );
                }
            }
            private bool _Important;
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged( string name ) {
                if( this.PropertyChanged != null )
                    this.PropertyChanged.Invoke( this , new PropertyChangedEventArgs( name ) );
            }
    
            public override string ToString() {
                return this.Name;
            }
        }
    
        public class CheckedListBoxEx : CheckedListBox {
            protected override void OnDrawItem( DrawItemEventArgs e ) {
                var item = this.Items[e.Index] as Info;
                if( item != null ) {
                    e.Graphics.FillRectangle( item.Important ? Brushes.Red : Brushes.White , e.Bounds );
                }
                base.OnDrawItem( e );
            }
        }
    }
    
[/code]




データバインディングで解決できます。  
Infoクラスは、1つの項目の状態を保持するためのクラスとなります。

CheckedListBoxクラスを継承したCheckedListBoxExを使用し、  
OnDrawItemメソッドをオーバーライドし、InfoクラスのImportantプロパティで見た目を変えています。

ObservableCollectionを使用していますがListでも、この場合は、構いません。

  * フォームでは、データバインディングに限界があります、できればWPFに移行を推奨します。 
  * 下記のコードは、参考に程度にしてください。適当実装なため…

* * *
[code]

    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1 {
        public partial class Form1 : Form {
            private readonly BindingSource binder = new BindingSource();
            private readonly ObservableCollection<Info> items = new ObservableCollection<Info>() {
                new Info() {
                    Checked = true,
                    Name = "hoge"
                }
            };
            public Form1() {
                InitializeComponent();
            }
    
            private void Form1_Load( object sender , EventArgs e ) {
                this.binder.DataSource = items;
                this.checkedListBox1.DataSource = this.binder;
            }
    
            private void button1_Click( object sender , EventArgs e ) {
                this.items[0].Important = !this.items[0].Important;
    
                this.binder.Add( new Info() {
                    Checked = true ,
                    Important = true ,
                    Name = "hoge"
                } );
            }
        }
    
        public sealed class Info : INotifyPropertyChanged {
            public bool Checked {
                get {
                    return this._Checked;
                }
                set {
                    if( this._Checked == value )
                        return;
                    this._Checked = value;
                    this.OnPropertyChanged( "Checked" );
                }
            }
            private bool _Checked;
    
            public string Name {
                get {
                    return this._Name;
                }
                set {
                    if( this._Name == value )
                        return;
                    this._Name = value;
                    this.OnPropertyChanged( "Name" );
                }
            }
            private string _Name;
    
            public bool Important {
                get {
                    return this._Important;
                }
                set {
                    if( this._Important == value )
                        return;
                    this._Important = value;
                    this.OnPropertyChanged( "Important" );
                }
            }
            private bool _Important;
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged( string name ) {
                if( this.PropertyChanged != null )
                    this.PropertyChanged.Invoke( this , new PropertyChangedEventArgs( name ) );
            }
    
            public override string ToString() {
                return this.Name;
            }
        }
    
        public class CheckedListBoxEx : CheckedListBox {
            protected override void OnDrawItem( DrawItemEventArgs e ) {
                var item = this.Items[e.Index] as Info;
                if( item != null ) {
                    e.Graphics.FillRectangle( item.Important ? Brushes.Red : Brushes.White , e.Bounds );
                }
                base.OnDrawItem( e );
            }
        }
    }
    
[/code]

