我有这个简单的XAML,如何更改Text
中TextBlock
中UserControl1
的{{1}}属性?
MainWindow
答案 0 :(得分:5)
WPF中的控件通常意味着某种“黑盒子”。你不应该(通常也不会)关心里面发生的事情。相反,如果要允许通信,则定义该控件的用户可以与之通信的公共接口。
在WPF中,此公共接口通常使用dependency properties。您也可以将常规(CLR)属性用于许多事情,但通常您希望允许数据绑定等内容,然后您需要依赖项属性。定义依赖属性比定义普通属性要复杂一些,因为它们需要额外完成一些工作。在Visual Studio中,虽然有propdp
代码段,但它可以帮助您通过几个简单的步骤添加所有样板代码。
因此,对于您的用户控件,我们有一个字符串属性,我们希望将其暴露给外部。因此,在该用户控件的代码隐藏中,我们将该属性定义为依赖属性:
public partial class ExampleUserControl : UserControl
{
public static readonly DependencyProperty SomeTextProperty =
DependencyProperty.Register("SomeText", typeof(string), typeof(ExampleUserControl), new PropertyMetadata("default value"));
public string SomeText
{
get { return (string)GetValue(SomeTextProperty); }
set { SetValue(SomeTextProperty, value); }
}
// this is the same old stuff
public ExampleUserControl()
{
InitializeComponent();
}
}
我们需要做的就是声明属性并使其可供组件的用户使用。现在我们只需要添加功能。由于没有涉及一些额外的逻辑,但是因为您只想将值委托给其他组件的属性(TextBlocks的Text
属性),我们可以使用数据绑定。这对大多数情况都有用:
<UserControl x:Class="SomeNamespace.ExampleUserControl" …
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<TextBlock Text="{Binding SomeText}" />
</StackPanel>
</UserControl>
为了使属性可以访问数据,我们将数据上下文设置为self
(即组件本身),然后我们可以将数据绑定到自己的属性。
当使用组件时,我们可以设置它的SomeText
属性:
<my:ExampleUserControl SomeText="Foo" />
因为它是一个依赖属性,我们也可以使用数据绑定从其他地方获取值(例如使用MVVM时的视图模型):
<my:ExampleUserControl SomeText="{Binding SomeTextProperty}" />
如果您为控件命名,您还可以在代码隐藏中访问它及其SomeText
属性,如果您需要这样做:
<my:ExampleUserControl x:Name="myControl" SomeText="Foo" />
<Button Click="ChangeText_Click" Content="Change text" />
private void ChangeText_Click (object sender, RoutedEventArgs e)
{
myControl.SomeText = "Bar";
}
最后,我们有一个可重用的组件,它与它所使用的应用程序完全分离。应用程序不需要知道该组件的实现,组件不需要知道它的位置将被使用。
答案 1 :(得分:2)
设置UserControl
的名称:
<refactorXaml:UserControl1 x:Name="MyUserControl1" />
在MainWindow中尝试像这样TextBlock
:
UserControl1 control = MyUserControl1;
var text = control.FindName("MyTextblock") as TextBlock;
if (text != null)
text.Background = Brushes.Red;
或者更短的时间:
var text = MyUserControl1.FindName("MyTextblock") as TextBlock;
if (text != null)
text.Background = Brushes.Red;
答案 2 :(得分:1)
如果你讨厌MVVM
,你可以添加一个公共财产。但MVVM将使更新源和目标变得容易,在这种情况下,您可以使用DependencyProperty
Without MVVM
这里应该如何看待你的UC
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public string TextBlockContent { get; set; }
}
您的MainWindow XAML
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:refactorXaml="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
</Grid.RowDefinitions>
<Grid>
<refactorXaml:UserControl1 Name="MyUserControl1"></refactorXaml:UserControl1>
</Grid>
<Grid Grid.Row="1">
<Button Click="ButtonBase_OnClick">Change Text</Button>
</Grid>
</Grid>
</Window>
您的MainWindow课程
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
MyUserControl1.TextBlockContent = "here your text ";
}
}