从WPF中的MainWindow访问UserControl中的对象

时间:2014-04-14 12:52:23

标签: c# wpf xaml

我有这个简单的XAML,如何更改TextTextBlockUserControl1的{​​{1}}属性?

MainWindow

3 个答案:

答案 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 "; 
        }
    }