2009-07-19 50 views
0

我想创建一个只包含RadioButtons的自定义控件。我想它使用如下:WPF中RadioButtons的CustomContainer问题

<RadioButtonHolder Orientation="Horizontal"> 
<RadioButton>RadioButton 1</RadioButton> 
<RadioButton>RadioButton 2</RadioButton> 
<RadioButton>RadioButton 3</RadioButton> 
<RadioButton> ...</RadioButton> 
</RadioButtonHolder> 

目前,我已经创建了一个自定义控件部分这样做。但是它似乎保留了一个正在收集的RadioButtons。它会将这个RadioButton集合添加到最后一个初始化的控件中。有谁知道这可能是为什么?任何帮助深表感谢。

编辑: 我有点想通了在这发生了什么。看起来,当对象初始化时,它会创建一个RadioButtons的列表,其中包含所有的RadioButtons,然后它将它作为子节点连接到窗口中的所有RadioButtonHolder控件。最后一个控件显示项目。

但我不知道如何防止这种情况,只能将内容本地化到每个控件。所以,如果我写道:

<RadioButtonHolder Name="RBH1"> 
<RadioButton Name="RB1">RB 1</RadioButton> 
<RadioButton Name="RB2">RB 2</RadioButton> 
</RadioButtonHolder> 
<RadioButtonHolder Name="RBH2"> 
<RadioButton Name="RB3">RB 3</RadioButton> 
<RadioButton Name="RB4">RB 4</RadioButton> 
</RadioButtonHolder> 

RB1 & RB2将显示在RBH1RB3 & RB4将显示为RBH2孩子。

我的代码如下:

CustomControl.cs

using System.Collections.Generic; 
using System.Windows; 
using Sytem.Windows.Controls; 
using System.Windows.Markup; 

namespace RandomControl 
{ 
[ContentProperty("Children")] 
public class CustomControl1 : Control 
{ 
    public static DependencyProperty ChildrenProperty = 
     DependencyProperty.Register("Children", typeof(List<RadioButton>), 
     typeof(CustomControl1),new PropertyMetadata(new List<RadioButton>())); 

    public List<RadioButton> Children 
    { 
     get { return (List<RadioButton>)GetValue(ChildrenProperty); } 
     set { SetValue(ChildrenProperty, value); } 
    } 

    static CustomControl1() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), 
      new FrameworkPropertyMetadata(typeof(CustomControl1))); 
    } 
} 
} 

Generic.xaml

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:RandomControl"> 
<Style TargetType="{x:Type local:CustomControl1}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:CustomControl1}"> 
       <Border Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}"> 
        <ItemsControl ItemsSource="{TemplateBinding Children}" 
         Background="{TemplateBinding Background}"> 
         <ItemsControl.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel></StackPanel> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
        </ItemsControl> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
</ResourceDictionary> 

回答

0

我刚刚发现我做错了什么!这是正确的在我面前,我没有看到它。

这个问题的问题是我有Children设置为DependencyProperty - 这意味着它将是静态的和全局的。所以整个RadioButton集合对于窗口中的所有控件都非常有用。 (事后看来这可能是为什么StackPanel,Canvas等没有Children属性作为DependencyProperty)。 您可以找到有关此here的更多信息。

感谢kek444发布一个更简单的方法来做到这一点。 :D

为了解决这个问题,你需要做的是删除DependencyProperty并将其声明为一个普通属性,私有set

我已经修改了代码:

CustomControl.cs

using System.Collections.Generic; 
using System.Windows; 
using Sytem.Windows.Controls; 
using System.Windows.Markup; 

namespace RandomControl 
{ 
    [ContentProperty("Children")] 
    public class CustomControl1 : Control 
    { 
     private ObservableCollection<RadioButton> _children; 
     private ItemsControl _control; 

     public ObservableCollection<RadioButton> Children 
     { 
      get 
      { 
       if (_children == null) 
        _children = new ObservableCollection<RadioButton>(); 
       return _children; 
      } 
      private set { _children = value; } 
     } 

     static CustomControl1() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), 
      new FrameworkPropertyMetadata(typeof(CustomControl1))); 
     } 

     public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 

      _control = base.GetTemplateChild("PART_ItemsControl") 
          as ItemsControl; 

      // display the radio buttons 
      if (_control != null) 
       _control.ItemsSource = Children; 
     } 
    } 
} 

Generic.xaml

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:RandomControl"> 
<Style TargetType="{x:Type local:CustomControl1}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:CustomControl1}"> 
       <Border Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}"> 
        <ItemsControl Name="PART_ItemControl" 
         Background="{TemplateBinding Background}"> 
         <ItemsControl.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel></StackPanel> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
        </ItemsControl> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
</ResourceDictionary> 
0

WPF旨在是尽可能简单易用,但也很新,开始时不容易。

所有你需要的是一些XAML这样的:

在你的窗口/页/用户控件添加资源

<Style x:Key="rbStyle" TargetType="RadioButton"> 
    <!--modify style to fit your needs--> 
    <Setter Property="Margin" Value="2"/> 
</Style> 

<Style x:Key="rbStackPanelStyle" TargetType="StackPanel"> 
    <!--modify style to fit your needs--> 
    <Setter Property="Orientation" Value="Vertical"/> 
    <Setter Property="Margin" Value="2"/> 
</Style> 

然后宣告你的 “radioButtonHolder” 任何需要的地方:

<StackPanel x:Name="rbHolder1" Style="{StaticResource rbStackPanelStyle}"> 
    <RadioButton Style="{StaticResource rbStyle}">RadioButton 1</RadioButton> 
    <RadioButton Style="{StaticResource rbStyle}">RadioButton 2</RadioButton> 
    <RadioButton Style="{StaticResource rbStyle}">RadioButton 3</RadioButton> 
    <RadioButton Style="{StaticResource rbStyle}">...</RadioButton> 
</StackPanel> 

根据你的问题,这应该符合你的需求。不需要自定义控件。其他许多修改可能适用于其中的样式和模板。

希望这有帮助,欢呼声。

+0

感谢这个! :)这样做是有道理的。 最初,我想让持有者做的是在RadioButton上叠加一个InkPresenter,以便我可以做一些奇特的笔交互。 – Nilu 2009-07-19 22:36:35