UserControl调用方法并在其类之外使用变量

时间:2010-06-29 20:47:32

标签: c# wpf xaml

我有一个看起来像这样的UserControl:

<UserControl x:Class="Test3.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Button Name="mybutton" Content="Button Content"/>
    </Grid>
</UserControl>

一个使用它的主窗口如下:

<Window Name="window_main" x:Class="Test3.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Test3">

    <StackPanel>
        <Label Name="mylabel" Content="Old Content"/>
        <local:UserControl1/>
    </StackPanel>
</Window>

我想要发生的是,mybutton的click事件处理程序将mylabel的内容设置为“New Content”。但是,这似乎是不可能的。实际上有办法做到这一点吗?

3 个答案:

答案 0 :(得分:1)

我选择自己回答这个问题,因为我的解决方案最终变得更加完整。我并不完全理解这样做的“正确”方法,但这就是我做到的方式:

Window1 window_reference = (Window1)(Window1.GetWindow((Button)sender));

在此之后,可以在编译时看到主窗口的子窗口(例如其他xaml控件)。

此外,更直接的方法是让UserControl的公共成员像这样:

namespace UIDD_Test
{
    public partial class UserControl1 : UserControl
    {
        public Window1 window_reference;

        public UserControl1()
        {
            InitializeComponent();
        }
    }
}

然后,只要适当,您可以将该成员设置为引用您想要的任何窗口。在我的情况下,我有一个Window1类派生自Window,所以我可以设置UserControl1类的成员,如下所示:

myusercontrol.window_reference = window_main;

我已经像这样设置了xaml:

<local:UserControl1 x:Name="myusercontrol"/>

window_main是主窗口的名称(它是一个Window1类)。

答案 1 :(得分:0)

有几种解决方案:

快速而肮脏:在mybutton点击事件处理程序上,使用Window找到父VisualTreeHelper,然后执行((Label) window.FindName("mylabel")).Content = "New Content"

干净的WPF方式:创建一个新类,添加一个属性object LabelContent和一个属性ICommand ChangeContentCommand,这将在执行时更改LabelContent。将此类设置为窗口的DataContext,将Content的{​​{1}}绑定到mylabelLabelContent属性Command绑定到{{ 1}}(用户控件将继承数据上下文)。

答案 2 :(得分:0)

执行所描述的最简单方法是利用事件路由并在Window XAML中添加处理程序:

<StackPanel ButtonBase.Click="Button_Click">
    <Label Name="mylabel" Content="Old Content"/>
    <local:UserControl1/>
</StackPanel>

和处理程序方法:

private void Button_Click(object sender, RoutedEventArgs e)
{
    mylabel.Content = "New Content";
}

我怀疑您在实际应用程序中可能会遇到更多复杂问题,因此您可能需要执行更多操作以通过检查其中的某些属性来验证点击是否来自正确的按钮。