2

こんにちは、リスト ビューの強制更新に少し問題があります。プロパティ Buffer を持つ TestClass オブジェクトを保持する ObservableCollection があります。

ObservalbeCollection は ViewModel BaseViewModel に存在します

public partial class MainPage : PhoneApplicationPage {
   // Constructor
    public MainPage() {
      InitializeComponent();
      this.DataContext = new BaseViewModel();
    }
  }
}

public class BaseViewModel : INotifyPropertyChanged {
  public ObservableCollection<TestClass> TestList { get; set; }
  public BaseViewModel() {
    TestList = new ObservableCollection<TestClass>();
    TestList.Add(new TestClass() { Buffer = "1", SomeValue = 1 });
    TestList.Add(new TestClass() { Buffer = "2", SomeValue = 2 });
    TestList.Add(new TestClass() { Buffer = "3", SomeValue = 3 });
    TestList.Add(new TestClass() { Buffer = "4", SomeValue = 4 });
  }

  private TestClass selectedItem;
  public TestClass SelectedItem {
    get {
      return selectedItem;
    }
    set {
      if (selectedItem == value) {
        return;
      }

      selectedItem = value;
      selectedItem.Buffer += "a";
      selectedItem.SomeValue += 1;
      selectedItem = null;
      RaisePropertyChanged("SelectedItem");
    }
  }

  #region notifie property changed
  public event PropertyChangedEventHandler PropertyChanged;

  public void RaisePropertyChanged(string propertyName) {
    PropertyChangedEventHandler handler = this.PropertyChanged;
    if (handler != null) {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
  }
  #endregion
}

public class TestClass : INotifyPropertyChanged  {

  public TestClass() {
  }

  public int SomeValue { get; set; }

  private string buffer;
  public string Buffer {
    get {
      return this.buffer;
    }
    set {
      this.buffer = value;
      RaisePropertyChanged("Buffer");        
    }
  }

  #region notifie property changed
  public event PropertyChangedEventHandler PropertyChanged;

  public void RaisePropertyChanged(string propertyName) {
    PropertyChangedEventHandler handler = this.PropertyChanged;
    if (handler != null) {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
  }
  #endregion
}

ビューモデルをページにバインドしています。

ページの xaml:

<phone:PhoneApplicationPage 
     xmlns:converters="clr-namespace:PhoneApp2.Test">

<phone:PhoneApplicationPage.Resources>
    <converters:TestClassConverter x:Key="testConverter"/>
</phone:PhoneApplicationPage.Resources>

<ListBox Grid.Row="1" x:Name="tasksListBox" ItemsSource="{Binding TestList}"
                 SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
                 >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="SomeText"/>
                    <TextBlock Text="{Binding Path=Buffer}"/>
                    <TextBlock Text="{Binding Converter={StaticResource testConverter}}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

バッファの変更中に 2 番目のテキストブロックが適切に更新されるようになりましたが、3 番目のテキストブロックは (リストの読み込み時に) 1 回だけ更新されます。コンバーターは一度だけ呼び出されます。

次の理由から、3 番目のオプションを使用したいと思います。

a) TestCalass を他のサブクラスの基本クラスとして使用します

b) TestClass タイプに応じて出力をフォーマットし、TestClass で設定されている他のパラメーターを使用したい

c) ローカライズ可能な文字列リソースを使用したいのですが、POCO オブジェクトではなく TestClass でそれらを使用したくありません。

編集: ソースコードを更新しました。2 番目のテキスト ボックスは変更されますが、3 番目のテキスト ボックスは変更されません。MainPage が存在することを期待するすべてのクラス:

namespace PhoneApp2.Test
4

2 に答える 2

0

更新時 TestListに呼び出すように変更すると動作しますか?RaisePropertyChanged

(完全な再現を提供していただければ、私は自分でチェックしたでしょう。)

于 2012-05-23T12:10:17.047 に答える
0

Binding は、そのコンポーネントの 1 つが更新され、かつこの更新がイベント (PropertyChanged など) によって通知されるとすぐに更新されます。

バインディング

<TextBlock Text="{Binding Converter={StaticResource testConverter}}"/>

は常に一定です: 常にまったく同じリスト エントリにバインドされます。したがって、このリスト エントリで何を変更しても、Binding には通知されません。

私の知る限り、INotifyCollectionChanged の CollectionChanged イベントが発生した場合、Binding は再評価されます。これを行うには、既に発生させた PropertyChanged イベントに加えて CollectionChanged イベントを発生させますが、これによりリスト全体が再評価され、パフォーマンスの問題が発生する可能性があります。

編集: TestList の CollectionChanged イベントを発生させる必要がありますが、これはおそらく不可能です。そのためには、ObservableCollection から BaseViewModel を取得する必要がある場合があります。

于 2012-05-25T08:46:34.210 に答える