/ /プロパティの変更後にDataTriggerが再評価されない-wpf、datatemplate、datatrigger

プロパティの変更後にDataTriggerが再評価されない - wpf、datatemplate、datatrigger

[元の]
私は ListBox それは持っています ItemsSource (これは、ウィンドウが作成されるときにコードビハインドで行われます)にデータバインドされます ObservableCollection。ザ ListBox その後、次のようになります DataTemplate アイテムに対して割り当てられた:

usercontrol.xaml

<ListBox x:Name="communicatorListPhoneControls"
ItemContainerStyle="{StaticResource templateForCalls}"/>

app.xaml

<Style x:Key="templateForCalls" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource templateRinging}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=hasBeenAnswered}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource templateAnswered}"/>
</DataTrigger>
</Style.Triggers>
</Setter>
</Style>

いつ ObservableCollection オブジェクトで更新され、これはに表示されます ListBox 正しいイニシャルで DataTemplateただし、 hasBeenAnswered プロパティがに設定されています true (デバッグすると、コレクションが正しいことがわかります) DataTrigger 再評価してから更新しません ListBox 正しいものを使用するには DataTemplate.

私は実装しました INotifyPropertyChanged オブジェクト内のイベント。テンプレート内で値にバインドされている場合は、値の更新を確認できます。そのちょうどそれ DataTrigger 再評価して正しいテンプレートに変更することはありません。

私は知っている DataTrigger ウィンドウを閉じて再度開くと、2番目のデータテンプレートが正しく適用されるため、バインディングは正しいです。 hasBeenAnswered に設定されています true.

[編集1]
Timoresによるコメントに続いて、私は次のことを試みました。

usercontrol.xaml

<ListBox x:Name="communicatorListPhoneControls"
ItemTemplate="{StaticResource communicatorCallTemplate}"/>`

app.xaml:

<DataTemplate x:Key="communicatorCallTemplate">
<Label x:Name="test">Not answered</Label>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=hasBeenAnswered}" Value="True">
<Setter TargetName="test" Property="Background" Value="Blue"/>
</DataTrigger>
</DataTemplate.Triggers>
</Label>
</DataTemplate>

今何が起こるかは最初の例と同様です、「未応答」ラベルに電話がかかってくると(これはリストボックスであるため、存在する電話ごとに1つです。通常、ウィンドウが読み込まれると電話はありません)、電話に応答してプロパティが表示されます。 hasBeenAnswered trueに設定されていますが、「未回答」は残ります同じ。ウィンドウを閉じて再度開くと(アクティブな呼び出しがプロパティhasBeenAnsweredをtrueに設定したまま)、背景が青色になります。したがって、ウィンドウが再実行されるまで、データトリガーは単に実行されていないように見えます。

回答:

回答№1は1

この例で私には奇妙に思えるのは、ItemTemplateの代わりにItemContainerStyleを使用していることです。

ItemContainerStyleは、ItemsSourceの各要素を含むListBoxItemに適用されます。 ListboxItemにはありません hasBeenAnswered プロパティなので、バインディングがどのように機能するかわかりません。

リストボックスにデータ型のDataTemplateを作成し、トリガーを使用して、 templateAnswered スタイル。

編集:OPがItemTemplateの提案を使用した後。

例を再現しようとしましたが、問題なく動作します。 これが私のXAMLです(スタイルは無視してください。これは単なる例です):

答えなかった

    <ListBox x:Name="communicatorListPhoneControls"
ItemTemplate="{StaticResource communicatorCallTemplate}"/>

<Button Margin="0,20,0,0" Click="OnToggleAnswer" Content="Toggle answer status" />
</StackPanel>

そして、コードビハインドでは:

public partial class Window1 : Window {

public Window1() {
InitializeComponent();

List<PhoneCall> lpc = new List<PhoneCall>()
{new PhoneCall(), new PhoneCall(), new PhoneCall(), new PhoneCall()};

communicatorListPhoneControls.ItemsSource = lpc;
}

private void OnToggleAnswer(object sender, RoutedEventArgs e) {

object o = communicatorListPhoneControls.SelectedItem;

if (o != null) {

PhoneCall pc = (PhoneCall) o;
pc.hasBeenAnswered = ! pc.hasBeenAnswered;
}
}
}

public class PhoneCall : INotifyPropertyChanged {

private bool _answered;


public bool hasBeenAnswered {
get { return _answered;  }
set {
if (_answered != value) {
_answered = value;
FirePropertyChanged("hasBeenAnswered");
}
}
}

private void FirePropertyChanged(string propName) {

if (PropertyChanged != null) {

PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}

これを再現して比較してみてくださいあなたのコード? 注:PropertyChangedに指定されたプロパティ名の最小のエラーが、動作を説明している可能性があります。トリガーは適切なプロパティに基づいている可能性がありますが、通知の名前のつづりが間違っている可能性があります。