[Originál]
mám ListBox
ktorý má svoje ItemsSource
(to sa deje v kóde zozadu ďalej, ako sa vytvára okno) databázy do ObservableCollection
, ListBox
potom má nasledovné DataTemplate
priradené k položkám:
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>
Kedy sa ObservableCollection
je aktualizovaný o objekt, zobrazí sa v ListBox
so správnym začiatočným písmenom DataTemplate
, keď však hasBeenAnswered
vlastnosť nastavená na true
(pri ladení vidím, že kolekcia je správna) DataTrigger
neprehodnocuje a potom neaktualizuje ListBox
používať správne DataTemplate
.
Implementoval som INotifyPropertyChanged
Udalosť v mojom objekte a ak je v šablóne viazaná na hodnotu, vidím aktualizáciu hodnoty. Je to len to DataTrigger
nebude prehodnocovať a meniť na správnu šablónu.
Viem to DataTrigger
väzba je správna, pretože ak zavriem okno a znova ho otvorím, bude sa správne aplikovať druhá šablóna údajov, pretože hasBeenAnswered
je nastavený na true
.
[upraviť 1]
V nadväznosti na komentáre Timores som vyskúšal nasledovné:
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>
Čo sa stane teraz, je podobné ako v prvom príklade,keď je hovor na štítku „Neodpovedané“, zobrazuje sa (jeden na každý hovor, ktorý existuje, pretože ide o zoznam - za normálnych okolností, keď sa načíta okno, nebudú žiadne hovory), hovor sa potom prijme a proptery hasBeenAnswered
je nastavený na true, napriek tomu zostáva „Neodpovedané“rovnaký. Ak zavriem okno a znova ho otvorím (pri aktívnom hovore so stále nastavenou vlastnosťou hasBeenAnswered na hodnotu true), bude pozadie modré. Zdá sa mi teda, že dátový spúšťač sa jednoducho nespustí, kým sa okno znovu nespustí.
odpovede:
1 pre odpoveď č. 1To, čo sa mi v príklade zdá čudné, je, že namiesto ItemTemplate používate ItemContainerStyle.
ItemContainerStyle sa vzťahuje na ListBoxItem, ktorý obsahuje každý prvok vo vašom zdroji ItemsSource. ListboxItem nemá hasBeenAnswered
majetok, takže nevidím, ako by väzba mohla fungovať.
Navrhujem vytvoriť DataTemplate pre dátový typ v zozname a použiť spúšťače na vykonanie rovnakých zmien ako vo vašom templateAnswered
štýl.
Edit: after OP used the suggestion of ItemTemplate.
Pokúsil som sa reprodukovať príklad a funguje mi to dobre. Tu je môj XAML (prosím ignorujte štýl, toto je iba príklad):
Neodpovedal
<ListBox x:Name="communicatorListPhoneControls"
ItemTemplate="{StaticResource communicatorCallTemplate}"/>
<Button Margin="0,20,0,0" Click="OnToggleAnswer" Content="Toggle answer status" />
</StackPanel>
A v kódexe:
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;
}
Môžete to skúsiť zopakovať a porovnať stvoj kód? Poznámka: Vaše správanie môže byť vysvetlené najmenšou chybou v názve vlastnosti, ktorá je uvedená v PropertyChanged. Spúšťač môže byť založený na správnom vlastníctve, ale oznámenie môže mať nesprávne napísaný názov.