none
如何在用户控件中定义TabControl类型的依赖属性? RRS feed

  • 问题

  • 我希望定义一个自定义控件的TabControl,并在TabControl中加入一些其他控件,如Button、ComboBox等。所以我选择了MainTabControl : UserControl,而没有直接继承TabControl.
    现在我在MainTabControl中定义了一个TabControl类型的依赖属性,目的在使用时可以对其进行设置。
    <Window ……>
      <Grid>
        <loc:MainTabControl BorderThickness="2" BorderBrush="Blue">
          <loc:MainTabControl.OutTabControl>
            <TabControl>
              <TabItem Header="a">aa</TabItem>
            </TabControl>
          </loc:MainTabControl.OutTabControl>
        </loc:MainTabControl>
      </Grid>
    </Window>
    
    我在MainTabControl中是这样定义的
    MainTabControl.xaml中没有放TabControl,只放了一个Button
    <UserControl ……>
      <Grid>
        <Button x:Name="btnClose" Content="X" 
            HorizontalAlignment="Right" VerticalAlignment="Top"
            Panel.ZIndex="999"
            Margin="0,5,5,0" />
      </Grid>
    </UserControl>
    MainTabControl.cs中定义了OutTabControl
    public partial class MainTabControl : UserControl {
    
    	public TabControl OutTabControl {
    		get { return (TabControl)GetValue(OutTabControlProperty); }
    		set { SetValue(OutTabControlProperty, value); }
    	}
    
    	// Using a DependencyProperty as the backing store for OutTabControl. This enables animation, styling, binding, etc...
    	public static readonly DependencyProperty OutTabControlProperty =
    		DependencyProperty.Register("OutTabControl", typeof(TabControl), typeof(MainTabControl)
    		//, new UIPropertyMetadata(new TabControl()) //“OutTabControl”属性的默认值无法绑定到特定线程。
    		//, new FrameworkPropertyMetadata(typeof(MainTabControl)) //默认值类型与属性“OutTabControl”类型不匹配。
    		);
    
    	public MainTabControl() {
    		InitializeComponent();
    		OutTabControl = new TabControl() {
    			Background = Brushes.LightBlue,
    
    		};
    		(this.Content as Grid).Children.Add(OutTabControl);
    	}
    }
    

    现在的问题是:
    1)我在其他窗体使用时,无法通过依赖属性方式给用户控件中的OutTabControl添加TabItem;
    2)如果我将OutTabControl定义在Xaml中,并声明<TabControl x:Name="OutTabControl" x:FieldModifier="public" .../>也无法在其他窗口中得到和使用。

    希望高手们给予详细的指导,谢谢!


    Sonny.Lin
    2011年6月6日 3:26

答案

  • 你已经在UserControl的构造中实例化了一个TabControl并且把它添加UserControl的Grid中了。然后你又指定了一个新的给他,但是你没有代码说把新的放入UserControl.

    按照你的思路,正确的应该是这样:

    UserControl 代码:

      public partial class MainTabControl : UserControl
      {
        public MainTabControl()
        {
          InitializeComponent();
        }
     
        public TabControl OutTabControl
        {
          get { return (TabControl)GetValue(OutTabControlProperty); }
          set { SetValue(OutTabControlProperty, value); }
        }
     
        // Using a DependencyProperty as the backing store for OutTabControl. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutTabControlProperty =
          DependencyProperty.Register("OutTabControl"typeof(TabControl), typeof(MainTabControl)
          , new UIPropertyMetadata(null, (o, e) =>
          {
            ((o as MainTabControl).Content as Grid).Children.Remove(e.OldValue as TabControl);
            ((o as MainTabControl).Content as Grid).Children.Add(e.NewValue as TabControl);
          })
          );
     
      }

     

    MainWindow XAML:

      <Grid>
        <loc:MainTabControl BorderThickness="2" BorderBrush="Blue">
          <loc:MainTabControl.OutTabControl>
            <TabControl>
              <TabItem Header="a">aa</TabItem>
            </TabControl>
          </loc:MainTabControl.OutTabControl>
        </loc:MainTabControl>
      </Grid>

     

     

    Sincerely,

     

     


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年6月6日 8:24
    版主

全部回复

  • 你已经在UserControl的构造中实例化了一个TabControl并且把它添加UserControl的Grid中了。然后你又指定了一个新的给他,但是你没有代码说把新的放入UserControl.

    按照你的思路,正确的应该是这样:

    UserControl 代码:

      public partial class MainTabControl : UserControl
      {
        public MainTabControl()
        {
          InitializeComponent();
        }
     
        public TabControl OutTabControl
        {
          get { return (TabControl)GetValue(OutTabControlProperty); }
          set { SetValue(OutTabControlProperty, value); }
        }
     
        // Using a DependencyProperty as the backing store for OutTabControl. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OutTabControlProperty =
          DependencyProperty.Register("OutTabControl"typeof(TabControl), typeof(MainTabControl)
          , new UIPropertyMetadata(null, (o, e) =>
          {
            ((o as MainTabControl).Content as Grid).Children.Remove(e.OldValue as TabControl);
            ((o as MainTabControl).Content as Grid).Children.Add(e.NewValue as TabControl);
          })
          );
     
      }

     

    MainWindow XAML:

      <Grid>
        <loc:MainTabControl BorderThickness="2" BorderBrush="Blue">
          <loc:MainTabControl.OutTabControl>
            <TabControl>
              <TabItem Header="a">aa</TabItem>
            </TabControl>
          </loc:MainTabControl.OutTabControl>
        </loc:MainTabControl>
      </Grid>

     

     

    Sincerely,

     

     


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年6月6日 8:24
    版主
  • 关于“OutTabControl”属性的默认值无法绑定到特定线程。 WPF 中依赖属性的默认值会通过一个特殊的线程来设置,所以对于Control来说,这个是不允许直接跨线程的。不过对于你的需求,用null就足够了,在从null变为一个TabControl实例的时候会触发 PropertyChanged 的回调,然后在PropertyChanged里面把这个新的TabCotnrol加到UserControl的Content中去。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年6月6日 8:38
    版主
  • Bob Bao感谢您的指导。像
    new UIPropertyMetadata(null, (o, e) =>
          {
            ((o as MainTabControl).Content as Grid).Children.Remove(e.OldValue as TabControl);
            ((o as MainTabControl).Content as Grid).Children.Add(e.NewValue as TabControl);
          })
    这种用法我是打破脑袋也想不到的,现在成功了,谢谢!
    Sonny.Lin
    2011年6月13日 10:58