[WPF] UC DependencyProperty Werkt 1e keer wel 2e keer niet

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • jvaneijk
  • Registratie: Mei 2003
  • Laatst online: 15-09-2024
Hoi allemaal,

Ik ben bezig met een usercontrol te maken welke een dependency property bevat genaamd Contacts.
Deze DP is gebind aan een ObservableCollection<Contact>.

So far so good.
Nu komt het echter, als ik de eerste keer een contact toevoeg aan mijn collection dan zie ik dat mijn DP in mijn usercontrol dit netjes oppakt en een propertychanged callback functie aanroept en zijn ding gaat doen.

Maar als ik echter de tweede keer wat toevoeg aan mijn collection dan kom ik nooi meer in mijn callback functie.

Ik hoop dat iemand mij kan vertellen hoe dit komt of hoe ik dit kan oplossen.

Mijn DP in de usercontrol
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public ObservableCollection<Contact> Contacts
        {
            get { return (ObservableCollection<Contact>)GetValue(ContactsProperty); }
            set
            {
                SetValue(ContactsProperty, value);
                _contacts = value;
               
                //Add the buttons to the stackPanel
                AddButtons();
            }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ContactsProperty =
            DependencyProperty.Register("Contacts", typeof(ObservableCollection<Contact>), typeof(AddContactButtonsControl), new FrameworkPropertyMetadata(null, NotifyContactsChanged){BindsTwoWayByDefault = true, DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged});
            //DependencyProperty.Register("Contacts", typeof(ObservableCollection<Contact>), typeof(AddContactButtonsControl), new UIPropertyMetadata(null, NotifyContactsChanged));

        private static void NotifyContactsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var addContactButtonsControl = sender as AddContactButtonsControl;
            if (addContactButtonsControl != null)
            {
                addContactButtonsControl.Contacts = e.NewValue as ObservableCollection<Contact>;
            }
        }


Mijn AddButtons:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void AddButtons()
        {
            var contactReadeService = new ContactReaderService();
            if (_contacts.Count > 0)
            {
                spContactButtons.Children.Clear();

                foreach (var contact in _contacts)
                {
                    var contactType  = contactReadeService.GetContactType(contact.ContactType);
                    var contactButton = new Button
                                            {
                                                Content = contactType.Name,
                                                Width = 72,
                                                Command = LoadContact,
                                                CommandParameter = contact
                                            };

                    spContactButtons.Children.Add(contactButton);
                }
            }
        }


Mijn XAML, aanroep van de UserControl (Contacts is ook een ObservableCollection):
code:
1
<custom:AddContactButtonsControl Contacts="{Binding Path=Contacts}" />

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • alwinuzz
  • Registratie: April 2008
  • Laatst online: 07-05 18:54
Er zit een verschil tussen dat je property verandert, en dat er iets in je property verandert (dus in je contacts collection). Met je NotifyContactsChanged van je volgens mij alleen het eerste op.

Om op de hoogte te blijven of er iets in je collection verandert (bijvoorbeeld contact toevoegen) moet je een event aan Contacts.CollectionChanged hangen.

Acties:
  • 0 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 17-03 09:43
Een ObservableCollection regelt dat al voor je.,. Je kan gewoon een listbox oid binden aan een OC en dan werkt het allemaal goed. Tenzij, volgens mij, als je de collectie zelf echt gaat veranderen (niet de inhoud, maar de lijst zelf).

Acties:
  • 0 Henk 'm!

  • alwinuzz
  • Registratie: April 2008
  • Laatst online: 07-05 18:54
Caelorum, hij gebruikt geen ListBox of ItemsControl, maar maakt z'n eigen control (custom:AddContactButtonsControl).


jvaneik, is het niet makkelijker om een ItemsControl te gebruiken met een template, en die dan te binden aan een ObservableCollection<ContactViewModel>. ContactViewModel is dan een adapter om Contact heen die de logica doet zoals contactReadeService.GetContactType.
Dan hoef je niet je eigen control te schrijven met dependency props en zo.

[ Voor 8% gewijzigd door alwinuzz op 20-07-2011 20:38 ]


Acties:
  • 0 Henk 'm!

  • jvaneijk
  • Registratie: Mei 2003
  • Laatst online: 15-09-2024
@alwinuzz

Dat is idd een heel erg goed idee. Ik was alleen even vergeten om dat op die manier op te lossen omdat ik de laatste dagen bezig ben geweest met UserControls bouwen :D

tnx i'll give it a try

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • jvaneijk
  • Registratie: Mei 2003
  • Laatst online: 15-09-2024
@alwinuzz

Ik heb het nu idd op jouw manier opgelost. Dit was de makkelijkste manier om ervoor te zorgen dat ik knopjes kan tonen op het scherm en ook nog alles netjes in 1 en dezelfde view :)

Voor de mensen die willen weten hoe ik het nu heb opgelost zie onderstaande

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<StackPanel Orientation="Horizontal">
                        <Button Content="Add+" Width="72" Height="27" Command="{Binding Path=AddContact}"/>
                        <ItemsControl ItemsSource="{Binding Path=Contacts}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <StackPanel Orientation="Horizontal"/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Button Content="{Binding ContactTypeString}" CommandParameter="{Binding}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ViewContact}" Width="72" Height="27" />
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • alwinuzz
  • Registratie: April 2008
  • Laatst online: 07-05 18:54
Jeej *O* mooi dat het nu werkt.
Pagina: 1