我想创建一个只包含RadioButtons的自定义控件。我想它的用法如下:
<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
&amp; RB2
和RBH1
及{}会显示RB3
RB4
将在RBH2
中显示为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)));
}
}
}
。
我的代码如下:
CustomControl.cs
<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>
Generic.xaml
{{1}}
答案 0 :(得分:0)
WPF旨在尽可能简单易用,但也非常新颖,并且一开始就不那么容易。
你需要的只是一些像这样的xaml:
在你的窗口/ page / usercontrol资源中添加
<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>
根据你的问题,这应该符合你的需求。不需要自定义控件。许多进一步的修改可以适用于其中的样式和模板。
希望这很有帮助,欢呼。
答案 1 :(得分:0)
我刚刚发现我做错了什么!它就在我面前,我没有看到它。
这个问题的问题在于我将Children
设置为DependencyProperty - 这意味着它将是静态和全局的。因此整个RadioButton
集合几乎可用于Window中的所有控件。 (事后看来,这可能是为什么StackPanel,Canvas等没有Children
属性作为DependencyProperty的原因。
您可以找到有关此here的更多信息。
感谢kek444发布更简单的方法。 :d
为了解决这个问题,您需要做的是删除DependencyProperty并将Children声明为具有私有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>