我是C#和wpf的新手。
如果在XAML中创建控件,则可以在代码中的任何位置访问其属性。但是,如果我在运行时创建控件,则当我尝试在其创建方法之外访问它时,它将显示为null
。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Button newBtn = new Button();
newBtn.Content = "Test";
newBtn.Name = "btnTest";
spTest.Children.Add(newBtn);
}
private void WPFButton_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//I want to access the button called btnTest and display the name of the button
}
}
最简单的方法是在字段中存储对按钮的引用:
public partial class MainWindow : Window
{
private Button _newBtn;
public MainWindow()
{
InitializeComponent();
_newBtn = new Button();
_newBtn.Content = "Test";
_newBtn.Name = "btnTest"; // < the name is not needed, because you already have a reference. (so you don't have to use FindControl)
spTest.Children.Add(_newBtn);
}
private void WPFButton_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//I want to access the button called btnTest and display the name of the button
_newBtn.Content = "Test2";
}
}
如果要存储多个控件,请使用字典或列表。
您在这里所做的一些复杂操作并不立即显而易见。其中之一是您不能仅仅定义一些处理程序,它就会起作用。您还必须订阅该事件。这是您需要插入事件的委托。
[像电器一样,在发生任何事情之前,都需要先将其插入。
这里有一些标记和代码来探索正在发生的事情。
因此,我可以看到将使用添加内容的列表框的消息。这些将显示为消息列表。
Title="MainWindow" Height="450" Width="800"
Button.Click="Window_Button_Click">
<Grid Name="agrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox Name="lb"
Grid.Column="1"/>
</Grid>
我在窗口级别连接了一个按钮单击处理程序。这将处理从窗口内任何地方冒起的单击事件。如果这对您来说是一个新概念,请阅读有关冒泡和隧道路由事件的详细信息。
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/routed-events-overview
然后,我将动态添加一个按钮。这将默认为网格的第0列,并显示在左侧。
您将看到是否尝试过。
我还订阅了按钮的两个事件。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Button newBtn = new Button();
newBtn.Content = "Test";
newBtn.Name = "btnTest";
agrid.Children.Add(newBtn);
newBtn.MouseUp += NewBtn_MouseUp;
newBtn.PreviewMouseDown += NewBtn_PreviewMouseDown;
}
private void NewBtn_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Button btn = sender as Button;
string theName = btn?.Name ?? "Something was Preview Mouse Downed but I don't know what";
lb.Items.Add($"Button PREVIEW MouseUp {theName}");
}
private void NewBtn_MouseUp(object sender, MouseButtonEventArgs e)
{
Button btn = sender as Button;
string theName = btn?.Name ?? "Something was Mouse Upped but I don't know what";
lb.Items.Add($"Button MouseUp {theName}");
}
private void Window_Button_Click(object sender, RoutedEventArgs e)
{
Button btn = e.OriginalSource as Button;
string theName = btn?.Name ?? "Something was CLICKED in the window but I don't know what";
lb.Items.Add($"Window Button Click {theName}");
}
}
上面的代码相当快速而且肮脏。
请注意,冒泡的事件处理程序对事件的原始来源很感兴趣,因为它已通过树,并且发送者也不会成为按钮。
f5旋转她并单击按钮。
有一个惊喜等着你。
没有来自鼠标的消息。
这是因为设计该按钮是为了单击而不是按下鼠标并向上移动鼠标。ButtonBase中的代码可以处理某些鼠标事件,并且由于它可以处理鼠标事件,因此处理程序将不会触发。
因此,我们希望可以解释一些有关事件的内容。
尽管有些事情我也要提到。
几乎所有wpf开发都使用MVVM,并将命令绑定到按钮的command属性,而不是完全使用事件。
[添加动态内容通常也不是这样的代码。
有很多选项,包括数据模板。首先使用称为viewmodel的方法,这种情况非常普遍。
您还可以通过将xaml作为字符串转换为控件来构建UI。这是构建UI的推荐方法,当您不能使用样式或模板时,UI必须是动态的。对您来说,现在研究这些东西为时过早,但仅供参考https://social.technet.microsoft.com/wiki/contents/articles/28797.wpf-dynamic-xaml.aspx