0

我想创建一个只包含 RadioButtons 的自定义控件。我想它被如下使用:

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

目前,我创建了一个部分执行此操作的自定义控件。然而,它似乎保留了 RadioButtons 的持续集合。它会将这个 RadioButtons 集合添加到最后一个初始化的控件中。有谁知道为什么会这样?任何帮助深表感谢。

编辑: 我有点弄清楚这里面发生了什么。似乎当对象被初始化时,它会创建一个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.

我的代码如下:

自定义控件.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)));
    }
 }
}

通用的.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>
4

2 回答 2

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>

根据您的问题,这应该符合您的需求。不需要自定义控件。并且许多进一步的修改可以适合其中的样式和模板。

希望这有帮助,干杯。

于 2009-07-19T12:58:03.603 回答
0

我才发现我做错了什么!它就在我面前,我没看到。

这个问题的问题是我Children设置了一个 DependencyProperty - 这意味着它将是静态的和全局的。因此,整个RadioButton集合几乎可用于 Window 中的所有控件。(事后看来,这可能是 StackPanel、Canvas 等没有该Children属性作为 DependencyProperty 的原因)。 您可以在此处找到有关此的更多信息。

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

为了解决这个问题,您需要做的是删除 DependencyProperty 并将 Children 声明为具有 private 的普通属性set

我修改了代码:

自定义控件.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;
        }
    }
}

通用的.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>
于 2009-07-21T02:29:17.327 回答