带子项的Wpf自定义控件

时间:2016-01-18 15:26:33

标签: wpf user-controls dependency-properties

我正在尝试使用以下功能创建“ModalPopup”自定义控件:

  1. 它始终显示主内容区Content
  2. 它有一个子PopupItems项集合,在主要内容区域的顶部显示(模态),并带有覆盖主要内容区域的半透明边框。
  3. 如果任何子项目的IsShown属性设置为true,则会显示它们,并且将禁用主要内容区域。
  4. 我已经让这个工作了,但我一直在设计器中遇到错误A value of type ‘ModalPopupItem’ cannot be added to a collection or dictionary of type ‘ObservableCollection’.我尝试过使用UIElementCollection,List,List,但我仍然遇到错误。在重新编译之前,Designer也没有反映我对xaml所做的任何更改,这非常令人沮丧。

    如何让设计师停止出现这些错误?

    ModalPopup:

        public class ModalPopup: ContentControl
        {
            public ModalPopup()
            {
                this.PopupItems = new ObservableCollection<ModalPopupItems>();
                this.Loaded += ModalPopup_Loaded;
            }
    
            private void ModalPopup_Loaded(object sender, RoutedEventArgs e)
            {
                foreach (ModalPopupItem item in this.PopupItem)
                {
                   Item.IsShownChanged += Item_IsShownChanged;
                }
                UpdateOverlay();
            }
    
            public static readonly DependencyProperty ShowOverylayProperty =
            DependencyProperty.Register.(“ShowOverlay”, typeof(bool), typeof(ModalPopup), new PropertyMetadata(true));
            public bool ShowOverlay
            {
                 get {return (bool)GetValue(ShowOverlayProperty);}
                 set {SetValue(ShowOverlayProperty, value);}
            }
    
            public static readonly DependencyProperty PopupItemsProperty = 
            DependencyProperty.Register.(“PopupItems”, typeof(ObservableCollection<ModalPopupItem>), typeof(ModalPopup))
            public ObservableCollection<ModalPopupItem>ShowOverlay
            {
                 get {return (ObservableCollection<ModalPopupItem>)GetValue(ShowOverlayProperty);}
                 set {SetValue(ShowOverlayProperty, value);}
            }
    
            private void UpdateOverlay()
            {
                 ShowOverlay = (PopupItems?.Any(item => item.IsShown) ?? false);
            }
    
            private void item_IsShownChanged(object sender, EventArgs e)
            {
                 UpdateOverlay();
            }
        }
    

    ModalPopupItem:

        public class ModalPopupItem: ContentControl
        {
                 public EventHandler IsShownChanged;
    
                 public static readonly DependencyProperty IsShownProperty =
                 DependencyProperty.Register(“IsShown”, typeof(bool), typeof(ModalPopupItem), new PropertyMetadata(true, IsShownChanged_Callback));
                 Public bool IsShown
                 {
                         get { return (bool)GetValue(IsShownProperty); }
                         set { SetValue(IsShownProperty, value); }
                 }
    
                 private static void IsShownChanged_Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
                 {
                          (d as ModalPopupItem).Visibility = (bool)e.NewValue ? Visibility.Visible : Visibility.Collapsed;
                          (d as ModalPopupItem).IsShownChanged?.Invoke(d, EventArgs.Empty);
                 }
        }
    

    资源文件:

       <Style TargetType=”local:ModalPopup”>
               <Style.Setters>
                     <Setter Property="Template">
                         <Setter.Value>
                              <ControlTemplate TargetType="local:ModalPopup">
                                  <Grid>
                                       <ContentPresenter Content="TemplateBinding Content}" 
                                                         IsEnabled="{TemplateBinding ShowOverlay, Converter={StaticResource InvertBool}}" />
                                       <ContentControl   Template="{StaticResource PopupTemplate}"
                                                         Visibility="{TemplateBinding ShowOverlay, Converter={StaticResource TrueToVisible}}">
                                             <ItemsControl ItemsSource="{TemplateBinding PopupItems}" />
                                       </ContentControl>
                              </ControlTemplate>
                         </Setter.Value>
                     </Setter>
               </Style.Setters>
       </Style>
    

    这就是我的控件的使用方式......

      <local:ModalPopup>
          <!-- Main Content Area -->
          <TextBlock Text="Main Content" Height=“200” Width=”200” />
    
          <!-- Popup Items -->
          <local:ModalPopup.PopupItems>
                <local:ModalPopupItem IsShown="False">Popup 1</ local:ModalPopupItem>
                <local:ModalPopupItem IsShown="True">Popup 2</ local:ModalPopupItem>
                <local:ModalPopupItem IsShown="{Binding ShowPopup3}">Popup 3</ local:ModalPopupItem>
           </local:ModalPopup.PopupItems>
       </local:ModalPopup>
    

0 个答案:

没有答案