1

最近、インデックス付きプロパティを発見しました。これは、私が扱っているデータをコレクションで表現するのが最適であるにもかかわらず、XAML データ バインディングで使用できるプロパティとして実装する必要があるというシナリオに対する完璧なソリューションのように見えます。インデックス付きプロパティを作成するテストから始めましたが、問題はありませんでしたが、バインドを機能させることができないようです。

誰かが私が間違っているところを指摘できますか?

インデックス付きプロパティを作成するためのネストされたクラスを含むテスト クラスを次に示します。

public class TestListProperty 
{

    public readonly ListProperty ListData;

    //---------------------------
    public class ListProperty : INotifyPropertyChanged 
    {
        private List<string> m_data;

        internal ListProperty()
        {
            m_data = new List<string>();
        }

        public string this[int index]
        {
            get
            {
                if ( m_data.Count > index )
                {
                    return m_data[index]; 
                }
                else
                {
                    return "Element not set for " + index.ToString();
                }
            }
            set
            {
                if ( m_data.Count > index )
                {
                    m_data[index] = value;
                }
                else
                {
                    m_data.Insert( index, value );
                }
                OnPropertyChanged( "Item[]" );
                Console.WriteLine( value );
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged( string propertyName )
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if ( handler != null ) handler( this, new PropertyChangedEventArgs( propertyName ) );
        }

    }
    //---------------------------
    public TestListProperty()
    {
        ListData = new ListProperty();
    }

}

XAML は次のとおりです。

<Window x:Class="TestIndexedProperties.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBox Width="200" Grid.Row="0" Text="{Binding Path=ListData[0], Mode=TwoWay}" />
        <TextBox Width="200" Grid.Row="1" Text="{Binding Path=ListData[1], Mode=TwoWay}" />
        <TextBox Width="200" Grid.Row="2" Text="{Binding Path=ListData[2], Mode=TwoWay}" />


    </Grid>
</Window>

そして、ここにウィンドウコードがあります:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        TestListProperty test = new TestListProperty();

        this.DataContext = test;

        test.ListData[0] = "ABC";
        test.ListData[1] = "Pleeez 2 wurk?";
        test.ListData[2] = "Oh well";

    }
}

助けてくれてありがとう!

4

1 に答える 1

0

リストが変更されたときにフロントエンドに通知するメカニズムがコードにありません。つまり、ListProperty は INotifyCollectionChanged ではなく INotifyPropertyChanged を実装しています。最も簡単な修正方法は、m_data を ObservableCollection 型に変更し、代わりに XAML コントロールをそれにバインドすることです。ただし、最初に実行しようとしていた目的が無効になる可能性があります。「適切な」方法は、CollectionChanged イベントをサブスクライブし、次の方法でメッセージを伝達することです。

public class TestListProperty
{
    public ListProperty ListData { get; private set; }

    //---------------------------
    public class ListProperty : INotifyCollectionChanged
    {
        private ObservableCollection<string> m_data;

        internal ListProperty()
        {
            m_data = new ObservableCollection<string>();
            m_data.CollectionChanged += (s, e) =>
            {
                if (CollectionChanged != null)
                    CollectionChanged(s, e);
            };
        }

        public string this[int index]
        {
            get
            {
                if (m_data.Count > index)
                {
                    return m_data[index];
                }
                else
                {
                    return "Element not set for " + index.ToString();
                }
            }
            set
            {
                if (m_data.Count > index)
                {
                    m_data[index] = value;
                }
                else
                {
                    m_data.Insert(index, value);
                }
                Console.WriteLine(value);
            }
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;

    }
    //---------------------------
    public TestListProperty()
    {
        ListData = new ListProperty();
    }
}
于 2013-12-12T00:52:21.063 に答える