WPF 中单选按钮的 CustomContainer 问题
我想创建一个仅包含单选按钮的自定义控件。 我想象它的使用方式如下:
<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
将显示在 RBH1
和 RB3
& 中。 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>
I want to create a custom control which would only contain RadioButtons. I imagine it being used as follows:
<RadioButtonHolder Orientation="Horizontal">
<RadioButton>RadioButton 1</RadioButton>
<RadioButton>RadioButton 2</RadioButton>
<RadioButton>RadioButton 3</RadioButton>
<RadioButton> ...</RadioButton>
</RadioButtonHolder>
Currently, I have created a custom control which partially does this. However it seems to keep an ongoing collection of the RadioButtons. And it would add this collection of RadioButtons to the last control initialized. Does anyone know why this may be? Any help is much appreciated.
Edit:
I kind of figured out what was happening in this. It seems that when the object is initialized it will create a list of RadioButtons
, which contains all the RadioButtons and then it would attach it to all the RadioButtonHolder
controls in the window as children. And the last control gets to display the items.
However I'm not sure how to prevent this and only localize the content to each control. So that if I wrote:
<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
will be displayed in RBH1
and RB3
& RB4
will be displayed as children in RBH2
.
My code is as follows:
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
WPF 旨在尽可能简单地使用,但它也很新,上手并不容易。
您所需要的只是像这样的一些xaml:
在您的窗口/页面/用户控件中添加资源
然后在需要的地方声明您的“radioButtonHolder”:
根据您的问题,这应该适合您的需求。 不需要自定义控件。 许多进一步的修改可以适合其中的样式和模板。
希望这对您有帮助,干杯。
WPF is intended to be as simple to use as possible, but is also very new and not so easy to get in the start.
All you need is a some xaml like this:
In your window/page/usercontrol Resources add
Then declare your "radioButtonHolder" wherever needed:
And that should fit your needs, according to your question. There's no need for a custom Control. And many further modifications could be fit inside styles and Templates therein.
Hope this was helpful, cheers.
我刚刚发现我做错了什么! 它就在我面前,但我没有看到。
这个问题的问题是我将
Children
设置为 DependencyProperty - 这意味着它将是静态的和全局的。 因此,整个RadioButton
集合几乎可供窗口中的所有控件使用。 (事后看来,这可能就是为什么 StackPanel、Canvas 等没有Children
属性作为 DependencyProperty)。您可以在此处找到有关此内容的更多信息。
感谢 kek444 发布了一种更简单的方法来执行此操作。 :D
为了解决这个问题,您需要删除 DependencyProperty 并将 Children 声明为具有私有
set
的普通属性。我修改了代码:
CustomControl.cs
Generic.xaml
I just found out what I was doing wrong! It was right in front of me and I didn't see it.
The issue with this problem was that I had
Children
set as a DependencyProperty - which means that it will be static and global. So the wholeRadioButton
collection was available pretty much to all the controls in the Window. (On hindsight which is probably why StackPanel, Canvas etc. doesn't have theChildren
property as a DependencyProperty).You can find more information about this here.
Thanks kek444 for posting a simpler way to do this. :D
In order to fix this what you need to do is remove the DependencyProperty and declare Children as a normal property with a private
set
.I have modified the code:
CustomControl.cs
Generic.xaml