2015-06-08 11 views
6

Mam pasek narzędzi z 3 DataTemplates dla moich przedmiotów:ObservableCollection.CollectionChanged nie wybrać właściwą DataTemplate Na pasku

<ToolBar ItemsSource="{Binding ContextActions}" Background="Transparent" ToolBarTray.IsLocked="True"> 
     <ToolBar.Resources> 
      <DataTemplate DataType="{x:Type viewModels:SimpleContextActionViewModel}"> 
       <Button Command="{Binding ActionCommand}" Style="{StaticResource ToolBarButtonStyle}" ToolTip="{userInterface:Translation Binding={Binding ToolTip}}"> 
        <ContentControl Template="{Binding Icon,Converter={StaticResource NameToResourceConverter}}" Margin="5" /> 
       </Button> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type viewModels:SeparatorViewModel}"> 
       <Rectangle Fill="{StaticResource SeparatorBrush}" Width="1" VerticalAlignment="Stretch" Margin="2,7" /> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type viewModels:PopupContextActionViewModel}"> 
       <Grid> 
        <ToggleButton IsChecked="{Binding ElementName=ContextActionPopup, Mode=TwoWay,Path=IsOpen}" Style="{StaticResource ToolBarButtonStyle}" 
            ToolTip="{userInterface:Translation Binding={Binding ToolTip}}"> 
         <ContentControl Template="{Binding Icon, Converter={StaticResource NameToResourceConverter}}" Margin="5" /> 
        </ToggleButton> 
        <Popup Name="ContextActionPopup" Height="150" Width="150" StaysOpen="False"> 
         <Border BorderBrush="{StaticResource PopupBorderBrush}" BorderThickness="1" Background="White"> 
          <ContentControl userInterface:RegionHelper.RegionName="{Binding RegionId}" /> 
         </Border> 
        </Popup> 
       </Grid> 
      </DataTemplate> 
     </ToolBar.Resources> 
    </ToolBar> 

ItemsSource jest ObservableCollection <obiekt>

Pierwsze trzy pozycje są już dostępne w konstruktorze mojego ViewModel, te trzy używają DataTemplates zgodnie z oczekiwaniami.

Jeśli dodaję kolejny "SimpleContextActionViewModel" do ObservableCollection, ToolBar dodaje tylko ContentPresenter, który wywołuje ToString. Jeśli dodać następującą linię do reasign z ObservableCollection na nowy, wszystko działa prawidłowo:

this.ContextActions = new ObservableCollection<object>(this.ContextActions); 

ten wyzwala NotifyPropertyChanged Realizacja mojego ViewModel i wszystkie przedmioty są odtworzone i wyglądać dobrze.

Dlaczego kolekcja CollectionChanged mojej ObservableCollection nie wybiera poprawnego DataTemplate, gdy PropertyChanged działa ?.

Jak to wygląda This is how it looks

Odpowiedz

3

Widziałem to już wcześniej z paskiem narzędzi, kiedy jest używane z kolekcją, która zmienia się gdziekolwiek poza konstruktorem.

Zamiast dodawać szablony danych w zasobach pasków narzędzi, dodaj je do pliku app.xaml, a zobaczysz, że Twój kod będzie działał tak, jak powinien. Spróbuj tego i daj mi znać, jeśli nadal nie działa

+0

Wypróbuję to jutro, chociaż bardzo trudno jest zarządzać tak specyficznymi szablonami danych na poziomie aplikacji. – Console

+0

@ Konsola nie jest pewna, dlaczego standardowe podejście nie działa. Natknąłem się na to kiedyś. Jeśli chcesz innego rozwiązania, czy możesz spróbować zastosować ItemTemplateSelector i sprawdzić, czy możesz przypisać DataTemplates w ten sposób? – Krishna

1

Nie jestem pewien, czy dotyczy to w Twoim przypadku, ale problem wydaje się zadziwiająco podobne do: Wiring up CollectionChanged and PropertyChanged (Or : Why do some WPF Bindings not refresh?)

od przyjętych odpowiedzi na ten link:

Jeśli nie udostępnisz WPF szablonu dla elementu danych (takiego jak Obiekty osób na liście), domyślnie będzie używana metoda ToString() o wyświetlacz. To jest członek, a nie własność, więc nie otrzymasz powiadomienia o zdarzeniu, gdy wartość się zmieni.

Jeśli dodasz DisplayMemberPath = "Nazwa" do swojego pola listy, wygeneruje on szablon , który będzie poprawnie powiązany z Nazwą Twojej osoby - która następnie będzie aktualizować się automatycznie zgodnie z oczekiwaniami.

Czy można zastosować DisplayMemberPath do przybornika, aby domyślnie nie używał ToString() do renderowania, a raczej wyzwalał narzędzie NotifyPropertyChanged?

+0

Nie sądzę, że jest to związane z moim przykładem, mam zdefiniowane DataTemplate do wyświetlania moich danych i działa zgodnie z oczekiwaniami dla niektórych elementów. Nie ma potrzeby korzystania z DisplayMemberPath, jeśli zdefiniujesz DataTemplate na temat sposobu wyświetlania klasy. I nie można osiągnąć tego, co chcę, za pomocą ścieżki elementu wyświetlającego. – Console

Powiązane problemy