从WPF中的主窗口提升用户控件上的事件

时间:2018-03-28 09:05:07

标签: c# wpf xaml event-handling

我的mainwindow.xaml中有一个文本框,当我进入文本框时,我希望我的usercontrol中的标签(称为View1.xaml)会相应更新。但是当我输入文本框时,我意识到用户控件中根本没有引发事件,你能告诉我哪个部分出错了吗?

该活动能够加入 TextBox_TextChanged_1

我的MainWindow.XAML

<Window xmlns:my="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:testapplication"  x:Class="testapplication.MainWindow"
        Title="MainWindow" Height="964" Width="790">
    <Grid >
        <Button x:Name="OpenView1" Content="Open Window 1" HorizontalAlignment="Left" Margin="33,70,0,0" VerticalAlignment="Top" Width="111" RenderTransformOrigin="0.279,1.409" Click="OpenView1_Click"/>
        <Button x:Name="OpenView2" Content="Open Window 2" HorizontalAlignment="Left" Margin="33,169,0,0" VerticalAlignment="Top" Width="111" Click="OpenView2_Click"/>
        <Button x:Name="OpenView3" Content="Open Window 3" HorizontalAlignment="Left" Margin="33,259,0,0" VerticalAlignment="Top" Width="111" Click="OpenView3_Click"/>

        <local:View1 x:Name="ViewOne" HorizontalAlignment="Left" Margin="33,332,0,0" VerticalAlignment="Top" Height="226" Width="204"  Visibility="Hidden"/>
        <local:View2 x:Name="ViewTwo" HorizontalAlignment="Left" Margin="284,332,0,0" VerticalAlignment="Top" Height="226" Width="208" Visibility="Hidden"/>
        <local:View3 x:Name="ViewThree" HorizontalAlignment="Left" Margin="534,332,0,0" VerticalAlignment="Top" Height="226" Width="196" Visibility="Hidden"/>
        <TextBox HorizontalAlignment="Left" Height="42" Margin="326,70,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="182" FontSize="22" TextChanged="TextBox_TextChanged_1"/>

    </Grid>
</Window>

我的MainWindow.cs

namespace testapplication
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
           //InitializeComponent();
        }

        //event handler
        public event EventHandler<EventArgs> changedText;

        private void OpenView1_Click(object sender, RoutedEventArgs e)
        {
            ViewOne.Visibility = Visibility.Visible;
        }

        private void OpenView2_Click(object sender, RoutedEventArgs e)
        {
            ViewTwo.Visibility = Visibility.Visible;
        }

        private void OpenView3_Click(object sender, RoutedEventArgs e)
        {
            ViewThree.Visibility = Visibility.Visible;
        }

        private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
        {

            if (changedText != null)
            {
               changedText(this, e);
            }
        }


    }
}

这是我的UserControl,称为View1.xaml,它包含在我的MainWindow.Xaml

namespace testapplication
{
    /// <summary>
    /// Interaction logic for View1.xaml
    /// </summary>
    public partial class View1 : UserControl
    {

        private MainWindow newWindow = new MainWindow();
        public View1()
        {
            InitializeComponent();

            newWindow.changedText += newWindow_ChangeText;
        }

        void newWindow_ChangeText(object sender, EventArgs e)
        {
            ViewOnelabel.Content = "Happy";
        }




    }
}

问题是我的 ViewOnelabel.Content =&#34; Happy&#34;根本没有执行,它保持不变

4 个答案:

答案 0 :(得分:-1)

这里的主要问题是您的View1类正在订阅新的MainWindow实例上的事件,而不是您的应用程序在启动时创建的MainWindow实例。 由于您的MainWindow类具有对View1类的引用(一个命名成员&#34; ViewOne&#34;),您只需从MainWindow类更改它。

private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
        {

            ViewOne.ViewOneLabel.Content = "Happy";
        }

摆脱chenagedText事件处理程序以及View1.xaml.cs中的所有代码......你不需要它。

注意:我希望你只是在玩这里并在这里学习......我绝不会宽恕以这种方式构建WPF应用程序。

答案 1 :(得分:-1)

您只能使用MainPage的事件。我建议你在UserControl中添加一个Property。就我而言,我称之为文本。

public string Text
{
    set { ViewOneLabel.Content = value; }
}

在MainWindow中使用TextChanged事件中的属性。

private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
    OpenView1.Text = TextBox.Text;
}

答案 2 :(得分:-1)

我想指出一些事情。

wpf中winforms标签的等价物是TextBlock。 wpf标签实际上是一种contentcontrol。因此内容属性。

在wpf中有路由事件。这些“泡沫”向上(和隧道向下)可视树。这意味着您可以从窗口内的用户控件中的控件处理窗口中的事件。

但主要是。 我鼓励你研究一下MVVM模式。 我已经汇总了一些说明这些要点的代码。 我建议只使用绑定和mvvm。

我的MainWindow标记:         Title =“MainWindow”Height =“350”Width =“525”

    TextBoxBase.TextChanged="Window_TextChanged"
    >
<Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
    <StackPanel>
        <Label Name="OutputLabel"/>
        <TextBlock Text="{Binding OutputString}"/>
        <local:UserControl1/>
    </StackPanel>

</Grid>

请注意,它处理一个textchanged事件,因为它的路由它将从其中的UserControl1获取事件。 代码背后:     public partial class MainWindow:Window     {         public MainWindow()         {             的InitializeComponent();         }

    private void Window_TextChanged(object sender, TextChangedEventArgs e)
    {
        OutputLabel.Content = $"Happy {((TextBox)e.OriginalSource).Text}";
    }
}

你没有对处理程序中的文本框中的文本做任何事情,但我有一些代码证明你可以从主窗口获得它,如果你想要的话。

我的viewmodel:     公共类MainWindowViewModel:INotifyPropertyChanged     {         private string inputString;

    public string InputString
    {
        get { return inputString; }
        set
        {
            inputString = value;
            OutputString = $"{inputString.Length} characters entered";
            RaisePropertyChanged();
        }
    }

    private string outputString;

    public string OutputString
    {
        get { return outputString; }
        set
        {
            outputString = value;
            RaisePropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Usercontrol1只有一个文本框:

<Grid>
    <TextBox Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>

当您在该文本框中键入内容时,文本将传输到我的viewmodel中的bound属性。这击中了我的二传手中的代码。这又设置了绑定到我的文本块的OutputString。

当我输入时,我的标签和文本块中的文字都会发生变化。

这是onedrive上我的示例链接 https://1drv.ms/u/s!AmPvL3r385QhgpgOPNKPs-veFJ2O3g

答案 3 :(得分:-1)

您正在MainWindow中创建UserControl的新实例。您要做的是将事件处理程序连接到您在屏幕上实际看到的实例。您可以使用Window.GetWindow方法获取对此的引用:

public partial class View1 : UserControl
{
    public View1()
    {
        InitializeComponent();

        Loaded += (s, e) => 
        {
            Window mainWindow = Window.GetWindow(this) as MainWindow;
            if(mainWindow != null)
                mainWindow.changedText += newWindow_ChangeText;
        };
    }

    void newWindow_ChangeText(object sender, EventArgs e)
    {
        ViewOnelabel.Content = "Happy";
    }
}