2

listboxitem 内部送信者に奇妙な状況が発生しました (この送信者に責任があると思いますが、よくわかりません...)

ListBox のItemTemplateがあります。

<ListBox x:Name="list">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel x:Name="stack_panel">
                    <Image Source="{Binding ImageSource}" Tap="Image_Tap"></Image>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
</ListBox>

ListBox のすべてのアイテムには、タップイベントのある画像があります。

private void Image_Tap(object sender, GestureEventArgs e)
{
   Image i = (Image)sender;
   i.Source = new BitmapImage(new Uri("Images/yellow.png", UriKind.RelativeOrAbsolute));
}

また、画像を簡単に変更するためのクラスもあります。

public class listItems
{
    public string ImageSource { get; set; }
}

右。これで、リストボックスにいくつかの要素を追加する準備ができました:

for (int i = 0; i < 100;i++)
   list.Items.Add(new listItems
   {
       ImageSource = "Images/black.png"
   });

それでは、ゼロ番目の太陽の画像をクリックしてみましょう。

画像1

全て大丈夫!続けて、2 番目の画像をクリックします。

画像2

ええ、太陽が輝いています..しかし..やめて、それは何ですか?0_o

ここに画像の説明を入力

このアイテムをクリックしていませんが、これのイメージが変わりました! これは、アイテムだけでなく、他のランダムなアイテム (53、81、...) でも発生します。

これについてあなたはどう思いますか?送信者は多くの要素を参照できますか?

4

1 に答える 1

1

これについてあなたはどう思いますか?

デフォルトでは、リスト ボックス コントロールはビジュアル アイテムを再利用してパフォーマンスを最適化します。必要に応じてオフにすることもできますが、100 個のアイテムの場合、パフォーマンスはもちろん低下します。

より良い解決策があります。行っていることの代わりに、ビジュアル ツリーだけでなく、モデルのどこかに選択状態を保存する必要があります。

アイテム クラスは次のようになります。

public class listItems: INotifyPropertyChanged
{
    bool _selected = false;
    public bool isSelected
    {
        get { return _selected; }
        set 
        {
            if( value == _selected )
                return;
            _selected = value;
            var pc = this.PropertyChanged;
            if( null != pc )
                pc( this, new PropertyChangedEventArgs( "ImageSource" ) );
        }
    }

    public string ImageSource { get { return _selected ? "Images/yellow.png" : "Images/black.png"; } }

    public event PropertyChangedEventHandler PropertyChanged;
}

INotifyPropertyChanged インターフェイスを使用すると、プロパティの変更についてビジュアル ツリーに通知できます。

タップ ハンドラは次のとおりです。

void Image_Tap( object sender, GestureEventArgs e )
{
    Image img = (Image)sender;
    listItems item = (listItems)img.DataContext;
    item.isSelected = true;
}
于 2012-11-16T23:31:41.443 に答える