C# 从WPF中的主窗口引发用户控件上的事件
在我的mainwindow.xaml中有一个文本框,当我输入文本框时,我希望usercontrol中的标签,即View1.xaml会相应地更新。然而,当我输入文本框时,我意识到事件根本不是在用户控件中引发的,你能告诉我哪个部分是错误的吗 事件可以在文本框中引发\u TextChanged\u 1 我的主窗口.XAMLC# 从WPF中的主窗口引发用户控件上的事件,c#,wpf,xaml,event-handling,C#,Wpf,Xaml,Event Handling,在我的mainwindow.xaml中有一个文本框,当我输入文本框时,我希望usercontrol中的标签,即View1.xaml会相应地更新。然而,当我输入文本框时,我意识到事件根本不是在用户控件中引发的,你能告诉我哪个部分是错误的吗 事件可以在文本框中引发\u TextChanged\u 1 我的主窗口.XAML <Window xmlns:my="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
<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);
}
}
}
}
命名空间测试应用程序
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
//初始化组件();
}
//事件处理程序
公共事件事件处理程序changedText;
私有void OpenView1_单击(对象发送者、路由目标)
{
ViewOne.Visibility=可见性.Visibility;
}
私有void openview 2_单击(对象发送方,路由目标)
{
ViewTwo.Visibility=可见性.Visibility;
}
私有void openview 3_单击(对象发送方,路由目标)
{
ViewThree.Visibility=可见性.Visibility;
}
私有无效文本框\u TextChanged\u 1(对象发送者,textchangedventargs e)
{
if(changedText!=null)
{
更改文本(本,e);
}
}
}
}
这是我的用户控件,称为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";
}
}
}
命名空间测试应用程序
{
///
///View1.xaml的交互逻辑
///
公共部分类View1:UserControl
{
私有主窗口newWindow=新主窗口();
公众意见1()
{
初始化组件();
newWindow.changedText+=newWindow\u ChangeText;
}
void newWindow_ChangeText(对象发送方,事件参数e)
{
ViewOnelabel.Content=“快乐”;
}
}
}
问题是myViewOnelabel.Content=“Happy”根本没有执行,它保持不变这里的主要问题是,View1类订阅的是新MainWindow实例上的事件,而不是应用程序启动时创建的MainWindow实例。 由于MainWindow类引用了View1类(命名成员“ViewOne”),因此只需从MainWindow类更改它即可
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
ViewOne.ViewOneLabel.Content = "Happy";
}
去掉chenagedText事件处理程序和View1.xaml.cs中的所有代码。。。你不需要它
注意:我希望你只是在这里玩和学习。。。我决不会容忍以这种方式构建WPF应用程序。您只能使用主页的事件。我建议您向UserControl添加一个属性。就我而言,我称之为文本
public string Text
{
set { ViewOneLabel.Content = value; }
}
在主窗口中,使用TextChanged事件中的属性
private void TextBox_TextChanged_1(object sender, TextChangedEventArgs e)
{
OpenView1.Text = TextBox.Text;
}
有几件事我想指出 wpf中winforms标签的等价物是TextBlock。wpf标签实际上是contentcontrol的一种类型。因此,内容属性 在wpf中有路由事件。这些“气泡”向上(向下)可视化树。这意味着您可以从窗口内usercontrol中的控件处理窗口中的事件 但主要是。 我鼓励您研究MVVM模式。 我已经编写了一些代码来说明这些要点。 不过我建议只使用绑定和mvvm 我的主窗口标记: Title=“MainWindow”Height=“350”Width=“525” 在处理程序中,您不会对文本框中的文本执行任何操作,但我有一些代码证明,如果您需要,可以从mainwindow获取这些文本 我的viewmodel: 公共类MainWindowViewModel:INotifyPropertyChanged { 私有字符串输入字符串
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中的绑定属性。这将命中我的setter中的代码。这反过来设置绑定到我的文本块的OutputString
键入时,标签和文本块中的文本都会发生更改
这是我在onedrive上的示例链接
您正在
UserControl
中创建MainWindow
的新实例。您要做的是将事件处理程序连接到您在屏幕上实际看到的实例。您可以使用窗口获取对此实例的引用。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";
}
}
我还在学习,我希望用eventhandler的方式构建一个应用程序,我能在view1上做些什么来让它工作吗?@user2399158这是一个相当复杂但很好的方法,可以将MVVM与WPF和导航一起使用,你似乎在追求这一点。使用MVVM。这可以通过绑定轻松完成。我怎么做?你能给我举个例子吗?JusDon’不要去youtube搜索WPF和MVVM。将会有大量的初学者教程。我真的建议你这样做。这会让你的生活更轻松。实际上不需要视图模型。UserControl应该只公开一个依赖项属性,它可以绑定到TextBox的文本属性。在UserControl的XAML中,你可以绑定它ViewOnelabel的内容通过RelativeSource绑定到UserControl dependency属性。@Fildor当然,重要的一点是可绑定的dependency属性,它可以绑定到视图模型以及其他元素的属性。
<Grid>
<TextBox Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
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";
}
}