wpf 将 XAML 属性值设置为用户控件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3182621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting XAML property value to user control
提问by aviv
I have a user control in WPF which i want the text of one of it's labels to be read from the XAML where it is used. Hence..
我在 WPF 中有一个用户控件,我希望从使用它的 XAML 读取其中一个标签的文本。因此..
My User Control:
我的用户控制:
<UserControl x:Class="muc">
<Label Foreground="#FF7800" FontSize="20" FontWeight="Bold">
<Label.Content>
<Binding ElementName="TestName" Path="." />
</Label.Content>
</Label>
</UserControl>
Then using it:
然后使用它:
<mycontorls:muc TestName="This is a test" />
But it doesn't works ... How can i read the properties ?
但它不起作用......我如何读取属性?
采纳答案by AlvinfromDiaspar
I've only done this with Silverlight, but i wouldnt be surprised if it works in the exact same way!
我只用 Silverlight 做过这个,但如果它以完全相同的方式工作,我不会感到惊讶!
// <summary>
// Xaml exposed TextExposedInXaml property.
// </summary>
public static readonly DependencyProperty TestNameProperty = DependencyProperty.Register("TestName", typeof(string), typeof(NameOfMyUserControl), new PropertyMetadata(string.empty));
// <summary>
// Gets or sets the control's text
// </summary>
public string TextExposedInXaml
{
get
{
return (string)GetValue(TestNameProperty );
}
set
{
SetValue(TestNameProperty , value);
// set the value of the control's text here...!
}
}
回答by sprite
I tried the first two answers and what I got worked in code but not on XAML (also doesn't let you see changes in the design view when using the control).
我尝试了前两个答案以及我在代码中得到的结果,而不是在 XAML 上得到的结果(在使用控件时也不会让您看到设计视图中的更改)。
To get a property working like any other native one, here is the full process: (The sample adds a dependency property of type Nullable to show in the control as text or a default if null)
要使属性像任何其他本机属性一样工作,完整过程如下:(示例添加了 Nullable 类型的依赖属性,以在控件中显示为文本或默认值(如果为 null)
In the code file:
1.a Define a dependency property:
public static readonly DependencyProperty MyNumberProperty = DependencyProperty.Register("MyNumber", typeof(Nullable<int>), typeof(MyUserControl), new PropertyMetadata(null, new PropertyChangedCallback(OnMyNumberChanged)));
1.b Implement the OnMyNumberChanged Callback:
private static void OnMyNumberChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args){ // When the color changes, set the icon color PlayButton MyUserControl muc = (MyUserControl)obj; Nullable<int> value = (Nullable<int>)args.NewValue; if (value != null) { muc.MyNumberTextBlock.Text = value.ToString(); } else { muc.MyNumberTextBlock.Text = "N/A"; } }
1.c implement the MyNumber property (not dependency) to use the dependency property for easy in code use:
public Nullable<int> MyNumber{ get { return (Nullable<int>)GetValue(MyNumberProperty); } set { SetValue(MyNumberProperty, value); OnTargetPowerChanged(this, new DependencyPropertyChangedEventArgs(TargetPowerProperty, value, value)); // Old value irrelevant. } }
In the XAML file bind the TextBlock control's text to the property (not dependency) to get the default value of the dependency property in case it is not set by the user of the control (assuming you called your root element of the user control "RootElement"):
在代码文件中:
1.a 定义一个依赖属性:
public static readonly DependencyProperty MyNumberProperty = DependencyProperty.Register("MyNumber", typeof(Nullable<int>), typeof(MyUserControl), new PropertyMetadata(null, new PropertyChangedCallback(OnMyNumberChanged)));
1.b 实现 OnMyNumberChanged 回调:
private static void OnMyNumberChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args){ // When the color changes, set the icon color PlayButton MyUserControl muc = (MyUserControl)obj; Nullable<int> value = (Nullable<int>)args.NewValue; if (value != null) { muc.MyNumberTextBlock.Text = value.ToString(); } else { muc.MyNumberTextBlock.Text = "N/A"; } }
1.c 实现 MyNumber 属性(非依赖)以使用依赖属性,方便代码使用:
public Nullable<int> MyNumber{ get { return (Nullable<int>)GetValue(MyNumberProperty); } set { SetValue(MyNumberProperty, value); OnTargetPowerChanged(this, new DependencyPropertyChangedEventArgs(TargetPowerProperty, value, value)); // Old value irrelevant. } }
在 XAML 文件中,将 TextBlock 控件的文本绑定到属性(不是依赖项)以获取依赖项属性的默认值,以防控件的用户未设置它(假设您将用户控件的根元素称为“RootElement” ”):
This code:
这段代码:
< TextBlock Name="MyNumberTextBlock" Text="{Binding MyNumber, ElementName=RootElement}"/>
回答by Quartermeister
If you give the root UserControl element a name, then you can refer to it using ElementName:
如果给根 UserControl 元素命名,则可以使用 ElementName 引用它:
<UserControl x:Class="muc"
Name="rootElement">
<Label Foreground="#FF7800" FontSize="20" FontWeight="Bold">
<Label.Content>
<Binding ElementName="rootElement" Path="TestName" />
</Label.Content>
</Label>
</UserControl>
You can also use the markup extension syntax to make it a little shorter:
您还可以使用标记扩展语法使其更短:
<UserControl x:Class="muc"
Name="rootElement">
<Label Foreground="#FF7800" FontSize="20" FontWeight="Bold"
Content="{Binding TestName, ElementName=rootElement}"/>
</UserControl>
Also remember that your control will be created before its properties are set. You will either need to implement INotifyPropertyChanged or have TestName
be a dependency property so that the binding is re-evaluated after the property is set.
还要记住,您的控件将在其属性设置之前创建。您将需要实现 INotifyPropertyChanged 或具有TestName
依赖属性,以便在设置属性后重新评估绑定。
回答by Pavel Minaev
{Binding ElementName=x}
binds to an elementwith name x
in the element tree, there is nothing here that deals with property TestName
. If you want a property on your user control, then you have to define the property in the class corresponding to that user control (in your case it would be muc
), and use {Binding RelativeSource={RelativeSource FindAncestor, ...}}
to reference it on your user control (see herefor details), or give it a name so you can use ElementName
.
{Binding ElementName=x}
结合到一个元素与名称x
的元素树,没有什么在这里,涉及财产TestName
。如果您想要用户控件上的属性,则必须在与该用户控件对应的类中定义该属性(在您的情况下为muc
),并用于{Binding RelativeSource={RelativeSource FindAncestor, ...}}
在您的用户控件上引用它(有关详细信息,请参见此处),或者给它一个名字,这样你就可以使用ElementName
.