2015-06-08 26 views
6

Tôi có một thanh công cụ với 3 DataTemplates cho mục của tôi:ObservableCollection.CollectionChanged không chọn DataTemplate đúng trên ToolBar

<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> 

Các ItemsSource là một ObservableCollection < đối tượng >

Ba mục đầu tiên đã có sẵn trong hàm tạo của ViewModel của tôi, ba hàm này sử dụng DataTemplates như mong đợi.

Nếu tôi thêm một "SimpleContextActionViewModel" khác vào ObservableCollection, thanh công cụ chỉ thêm một ContentPresenter gọi ToString. Nếu tôi thêm các dòng sau vào reasign ObservableCollection để một hình mới, mọi thứ hoạt động tốt:

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

này gây nên việc thực hiện NotifyPropertyChanged của ViewModel của tôi và tất cả các mục được tái tạo và tìm kiếm tốt.

Tại sao một CollectionChanged của ObservableCollection của tôi không chọn DataTemplate hợp lệ trong khi PropertyChanged làm gì ?.

Đây là cách nó trông This is how it looks

Trả lời

3

Tôi đã thấy điều này xảy ra trước đây với thanh công cụ khi được sử dụng với bộ sưu tập được thay đổi ở bất kỳ nơi nào khác ngoài hàm tạo.

Thay vì thêm mẫu dữ liệu của bạn trong tài nguyên thanh công cụ, hãy thêm chúng vào ứng dụng.xaml sau đó bạn sẽ thấy rằng mã của bạn sẽ hoạt động bình thường. Hãy thử điều này và cho tôi biết nếu nó vẫn không hoạt động

+0

Tôi sẽ thử điều đó vào ngày mai, mặc dù nó cảm thấy thực sự bẩn để quản lý các mẫu dữ liệu cụ thể ở cấp ứng dụng. – Console

+0

@Console không chắc chắn chính xác lý do tại sao phương pháp tiếp cận chuẩn không hoạt động. Tôi tình cờ gặp điều này đôi khi trước đây. Nếu bạn muốn có một giải pháp khác, bạn có thể thử thực hiện một ItemTemplateSelector và xem liệu bạn có thể gán DataTemplates theo cách đó không? – Krishna

1

Tôi không chắc chắn liệu này áp dụng trong trường hợp của bạn, nhưng vấn đề của bạn có vẻ khá tương tự như: Wiring up CollectionChanged and PropertyChanged (Or : Why do some WPF Bindings not refresh?)

Từ câu trả lời được chấp nhận vào liên kết đó:

Nếu bạn không cung cấp WPF với mẫu cho mục dữ liệu (chẳng hạn như đối tượng Person trong danh sách của bạn), nó sẽ mặc định sử dụng phương thức ToString() t o hiển thị. Đó là một thành viên, không phải là tài sản và do đó bạn không nhận được thông báo sự kiện khi giá trị thay đổi.

Nếu bạn thêm DisplayMemberPath = "Name" vào hộp danh sách, nó sẽ tạo mẫu liên kết đúng với Tên của người bạn - sẽ sau đó tự động cập nhật như bạn mong đợi.

Bạn có thể áp dụng DisplayMemberPath vào hộp công cụ để không sử dụng ToString() theo mặc định để hiển thị, mà là kích hoạt NotifyPropertyChanged?

+0

Tôi không nghĩ điều này liên quan đến ví dụ của mình, tôi đã xác định DataTemplate để hiển thị dữ liệu của mình và nó hoạt động như mong đợi đối với một số mục. Không cần sử dụng DisplayMemberPath nếu bạn định nghĩa một DataTemplate về cách hiển thị một lớp. Và nó không thể đạt được những gì tôi muốn với một đường dẫn thành viên hiển thị. – Console

Các vấn đề liên quan