【发布时间】:2019-07-24 08:59:04
【问题描述】:
问题似乎很简单:
我有一个UserControl,我的控件包含一个Button。
Button 元素可以设置样式。但我不想在我的控制中拥有样式定义。我的控件甚至没有 XAML。我想在 XAML 中设置这样的样式:
<Style TargetType="local:MyControl">
<Setter Property="ItsButton.Padding" Value="8" />
</Style>
这样不行。它是如何工作的?
我知道我可以将任何内部控件的属性绑定到我的 UserControl 依赖属性,它会起作用。但是绑定很多属性有点矫枉过正,做简单的事情真的需要这么多的编码,还是更容易/更快/更简单的方法?
顺便说一句,这对你来说看起来并不过分,想象一下我有很多内部控件,比如按钮,比如说InputBoxes 等等。
这是示例控制代码:
class Installable : UserControl {
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value",
typeof(object),
typeof(Installable),
new FrameworkPropertyMetadata(OnValueChanged));
public static readonly DependencyProperty InstallButtonProperty = DependencyProperty.Register(
"InstallButton",
typeof(Button),
typeof(Installable),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None));
public static readonly DependencyProperty InstallTextProperty = DependencyProperty.Register(
"InstallText",
typeof(string),
typeof(Installable),
new FrameworkPropertyMetadata(OnInstallTextChanged));
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
"Command",
typeof(ICommand),
typeof(Installable),
new FrameworkPropertyMetadata(OnCommandChanged));
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register(
"CommandParameter",
typeof(object),
typeof(Installable),
new FrameworkPropertyMetadata(OnCommandParameterChanged));
public object Value {
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public Button InstallButton {
get => (Button)GetValue(InstallButtonProperty);
set => SetValue(InstallButtonProperty, value);
}
public string InstallText {
get => (string)GetValue(InstallTextProperty);
set => SetValue(InstallTextProperty, value);
}
public ICommand Command {
get => (ICommand)GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
public object CommandParameter {
get => GetValue(CommandParameterProperty);
set => SetValue(CommandParameterProperty, value);
}
public Installable() {
InstallButton = new Button();
Content = Value ?? InstallButton;
InstallText = "Install";
}
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var control = d as Installable;
var value = e.NewValue;
control.Content = value ?? control.InstallButton;
}
private static void OnInstallTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var control = d as Installable;
var text = e.NewValue as string;
control.InstallButton.Content = text;
}
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var control = d as Installable;
var command = e.NewValue as ICommand;
control.InstallButton.Command = command;
}
private static void OnCommandParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var control = d as Installable;
var value = e.NewValue;
control.InstallButton.CommandParameter = value;
}
}
控件在不为空时显示其Value,否则为InstallButton。
就像如果值未设置 - 它包含按钮,当值设置时 - 包含值。该控件的作用就像魅力一样,但是当我在MainWindow XAML 中设置Button 样式时,它不会影响我的UserControl 中的按钮。
也许我的Button 可以以某种方式继承Button 在MainWindow XAML 中定义的样式?
【问题讨论】:
-
那么您希望能够让控件样式的消费者使用按钮吗?如果没有,并且已经修复,也可以在代码中设置。
-
样式必须可以来自主样式表 XAML 字典。