2010-03-17 3 views
3

종속성 속성이 WPF 컨텍스트 메뉴에 표시되는 목록의 내용을 만들려고합니다.WPF 컨텍스트 메뉴가 List <> 종속성 속성에 바인딩되었습니다.

나는 다음과 같은 종속성 속성을 가진 클래스, 푸의 (데이터 보유 클래스)의 목록이 : 나는 다음과 같은 정적 자원을 설정 XAML에서

public List<Foo> FooList 
    { 
     get { return (List<Foo>)GetValue(FooListProperty); } 
     set { SetValue(FooListProperty, value); } 
    } 
    public static DependencyProperty FooListProperty = 
     DependencyProperty.Register("FooList", typeof(List<Foo>), 
      typeof(FooButton)); 

, 나는 가정을 자사의 상황에 맞는 메뉴의 밤은 이후 필요 비주얼 트리의 다음의 ResourceDictionary에

또한
<UserControl.Resources> 
    <ResourceDictionary>    
     <CollectionViewSource 
      x:Key="FooListSource" 
      Source="{Binding FooList}"/> 

     <!-- ... --> 

    </ResourceDictionary> 
</UserControl.Resources> 

부는 상기 아이템이 실제 콘텍스트 메뉴에 표시하기 위해 필요로되는 CompositeCollection이다. UserControl CanStop 속성이 true이면 구분 기호와 중지 명령도 표시됩니다. 이러한 바인딩은 MenuItem 자체가 나타나기는하지만 실패합니다. 그래서 왜 이것이 실패 하는지를 알 수 있다면 List가 더 쉬울 수도 있습니다.

<CompositeCollection x:Key="FooListItems"> 
    <CollectionContainer 
     Collection="{Binding Source={StaticResource FooListSource}}"/> 
    <Separator 
     Visibility="{Binding CanStop, 
      Converter={StaticResource VisibleIfTrue}}" /> 
    <MenuItem 
     Command="{x:Static Buttons:FooButton.Stop}" 
     Header="Stop" 
     Visibility="{Binding CanStop, 
      Converter={StaticResource VisibleIfTrue}}"/> 
</CompositeCollection> 

그리고

마지막으로 또한 ResourceDictionary의 상황에 맞는 메뉴 자체 :
<ContextMenu 
    x:Key="FooButtonMenu" 
    ItemsSource="{Binding Source={StaticResource FooListItems}}" 
    ItemTemplate="{StaticResource FooListTemplate}" 
    <ContextMenu.CommandBindings> 
     <CommandBinding 
       Command="{x:Static Buttons:FooButton.Stop}" 
       Executed="Stop_Executed" /> 
    </ContextMenu.CommandBindings> 
</ContextMenu> 

내가 많은 코드하지만이 작품은 어떤 간단하게 만들 수 있습니다 임 확실하지에 임 게시 방법을 느낍니다. 구분 기호와 하드 코드 된 메뉴 항목 만 나타납니다. 그래서 무언가가 바인딩으로 엉망이되어야합니다. 바인딩은 일반적으로 어려운 일이 아니지만 지금은 정말 내가 잃어버린 느낌이 같은 나무의 일부가 아닌 그 무언가를 묶고 싶습니다.

모든 의견을 환영합니다. :)

+0

어떻게 FooList DependencyProperty를 사용하고 있습니까? 특히, 완전히 채워진 목록을 속성에 할당 했습니까? 아니면 빈 목록을 속성에 할당하고 나중에 목록을 채우고 있습니까? DependencyProperty는 완전히 새로운 목록에 할당을 전파하지만 목록의 변경 사항을 모니터링하려면 ObservableCollection 또는 INotifyCollectionChanged의 다른 구현을 사용해야합니다. –

+0

레거시 시스템에서 읽을 데이터를 트리거하는 함수가 호출되며,'FooList를 수행하는 데이터를 순환합니다.추가 (myNewFoo);'. 'List <>'를 ObservableCollection <>으로 바꿔야한다는 말입니까? – Mizipzor

+0

어 .. 모든게 나에게 좋아 보인다! 데모 프로젝트를 어딘가에 업로드 할 수 있습니까? DataContext가 누락 되었습니까? – mg007

답변

1

의심스러운 것이므로 ObservableCollection<Foo> 대신 List<Foo>을 사용하면 문제가 발생한 것으로 보입니다. List<Foo>은 속성 변경을 알리지 않으므로 WPF에서 항목을 추가하거나 제거했다는 것을 인식하게하는 유일한 방법은 FooList 속성을 다른 것으로 임시 설정 한 다음 다시 설정하는 것입니다.

CLR 속성으로 전환 할 필요가 없습니다. List<Foo>에서 ObservableCollection<Foo>으로 변경하십시오.

CompositeCollection의 바인딩이 작동하지 않는 이유는 CompositeCollection이 DependencyObject가 아니기 때문에 DataContext을 상속받을 수 없기 때문입니다.

+0

DependencyObject를 사용할 수있는 CompositeCollection에 대한 대안이 있습니까? 상황에 맞는 메뉴가 표시되면 항목이 업데이트되지만 코드 비하인드에서 간단한 방법으로이 작업을 수행했지만 지금은 데이터 바인딩을 시도하려고합니다. – Mizipzor

+0

ObservableCollection에 대한 List를 바꾸는 것만으로 효과가있는 것 같습니다. – Mizipzor

0

FooList이 (가) 종속성 속성으로 된 이유는 알 수 없습니다. 종속성 속성을 만드는 가장 일반적인 이유는 바인딩의 대상이 아닙니다. 콜백을 구현하지 않았으므로 변경 알림을 수행 할 수 없습니다 (종속성 속성을 만드는 두 번째 가장 일반적인 이유). 가치 상속에 사용하지 않습니다. 그럼 왜?

FooList은 (또는 INotifyCollectionChanged을 구현하는 모든 클래스)의 일반 CLR 속성이 될 것입니다. 이렇게하면 필요한 변경 알림을 모두 처리 할 수 ​​있습니다. 적어도 지금까지 게시 한 코드에 필요합니다.

+0

이것은 내게 빨간 청어처럼 들린다. 우리는 하루 종일 FooList를 DependencyProperty 또는 CLR 속성으로 만드는 것이 적절한 지 논쟁 할 수 있습니다. 아래쪽은 DependencyProperty가 CLR 속성이 할 수있는 모든 것을 할 수 있다는 것입니다. 어떤 시나리오에서는 이것이 좋지 않은 선택이라고 주장 할 수도 있지만 (이것이 내가 그 중 하나인지는 잘 모르겠다.), mizipzor가 갖는 문제와 관련이 없다. –

+0

종속성 속성인지 여부는 중요하지 않습니다. 실제로 중요한 것은 그것의 타입이'INotifyCollectionChanged'를 구현하는 콜렉션이라는 것입니다. –

관련 문제