سؤال

إبداعي
انا املك 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 ملزمة صحيحة لأنه إذا أغلقت النافذة وفتحها مرة أخرى، فسيؤدي ذلك بشكل صحيح إلى تطبيق DataTemplate الثاني، لأن hasBeenAnswered تم تعيين إلى true.

تحرير 1
متابعة من التعليقات التي أدلى بها تيمورس جربت ما يلي:

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>

ما يحدث الآن يشبه المثال الأول، عندما تأتي مكالمة في عروض تسمية "غير المجابة" (واحد لكل مكالمة موجودة لأن هذه قائمة قائمة - عادة عندما تكون الأحمال النافذة لن تكون هناك مكالمات)، تكون المكالمة بعد ذلك أجاب والبيرن hasBeenAnswered تم تعيينه إلى True، ومع ذلك، فإن "عدم الإجابة" لا يزال هو نفسه. إذا قمت بإغلاق النافذة، وإعادة فتحه مرة أخرى (مع المكالمة النشطة التي لا تزال مع مجموعة الممتلكات Herbeenanswered إلى TRUE)، فإن الخلفية هي ثم أزرق. لذلك، يبدو لي مثل DataTrigger لم يتم تشغيله ببساطة، حتى يتم إعادة تشغيل النافذة.

هل كانت مفيدة؟

المحلول

ما يبدو غريبا بالنسبة لي في المثال هو أنك تستخدم ItemContainersTyle بدلا من عنصر.

ينطبق ItemContainerstyley على ListBoxitem الذي يحتوي على كل عنصر في OcticeSource. ListBoxitem لا يحتوي على hasBeenAnswered الممتلكات، لذلك لا أرى كيف يمكن أن تعمل الربط.

أقترح إنشاء DataTemplate لنوع البيانات في مربع القائمة الخاص بك واستخدام المشغلات لجعل نفس التغييرات كما هو الحال في templateAnswered نمط.

تحرير: بعد استخدام OP اقتراح العنصر.

حاولت إعادة إنتاج المثال، ويعمل بشكل جيد بالنسبة لي. هنا هو بلدي 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;
}

هل يمكن أن تحاول إعادة إنتاج هذا ومقارنة مع الكود الخاص بك؟ ملاحظة: أصغر خطأ في اسم العقار المعطى للمستخدمين يمكن أن يفسر سلوكك. يمكن أن يستند الزناد إلى الممتلكات المناسبة، ولكن الإخطار قد يكون له اسم أخطاء إملائية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top