这是我在stackoverlow上的第一篇文章,我认为它是C#和WPF最好的在线帮助网站。
我在过去三天里研究了大约6个小时,试图找出如何将按钮处理程序事件附加到我在样式中定义的按钮。我的情况似乎与我在网上看到的所有其他例子不同。所以这里,我当然感谢你的意见。
来自MainWindow.xaml的片段,我在Grid中定义了以下
<ScrollViewer Grid.Column="2" Grid.ColumnSpan="2"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Hidden"
Background="AliceBlue">
<ItemsControl ItemsSource="{Binding LaserDataItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="AliceBlue" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
LaserDataItems上的此绑定将包含要显示的UserControl列表。这些是根据需要动态创建的。但我实际上试图在控件的代码中完成我的所有工作(下面)
在我向您展示UserControl之前,这里是我将与UserControl一起使用的Style。 我的第一个目标是在加载按钮后在按钮上创建点击事件
<Style x:Key="HeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Button x:Name="MyButton" Height="20"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是userControl
<UserControl x:Class="EClient.Controls.GetAllLaserData"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DataGrid Name="laserDataGrid"
ColumnHeaderStyle="{StaticResource HeaderStyle}"
AutoGenerateColumns="False"
ItemsSource="{Binding }"
IsReadOnly="True"
RowHeaderWidth="0"
Height="567"
VerticalAlignment="Top"
RowHeight="17">
<DataGrid.Columns>
<DataGridTextColumn
Width="53"
Header="{Binding HeaderName}"
Binding="{Binding Name}"></DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="IsEnabled" Value="False"/>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</UserControl>
在此UserControl的DataGrid中是ColumnHeaderStyle,它被赋予模板:HeaderStyle。这个样式有一个按钮,我需要在实例化时附加一个单击处理程序。 我该怎么做呢。 我试图通过重写OnApplyTemplate方法来访问它,但我尝试的所有东西都返回null。当此方法运行时,按钮是否可能尚未实例化?必须有办法到达这个按钮。
当我运行它并成功创建这些UserControls的列表(它们是datagrids)时,可以在第一个单元格(每个网格的标题)中看到一个按钮。
我还尝试使用遍历可视化树的通用例程,但无济于事。实际上这是我应该追求的东西,我真的不知所措。
2013年10月26日增加了以下内容
虽然我找到了另一个解决这个问题的方法,但我仍然有兴趣解决它。我真的认为这是一个非常好的问题。
无论如何,我想我会画一张我想要做的事。也许这会对手头的问题有更好的认识。
答案 0 :(得分:0)
不是一个直接的答案 - 但这是我如何解决问题。我不使用datagrids - 而是使用itemscontrols,所以我必须使用ItemsControl作为示例。
处理列表中的按钮时,我通常将包含按钮的控件拆分为自己的用户控件(根据需要应用样式)。然后我会在后台有一个事件处理程序,例如XAML
<UserControl x:Class="BindableTest.UserControls.CatItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0 0 10 0">
<Label Content="{Binding Path=Model.DisplayNumber}" HorizontalAlignment="Left" Height="25" Width="25" />
<TextBox BorderBrush="Black" Text="{Binding Path=Model.SomeText, UpdateSourceTrigger=PropertyChanged}" Width="150" Height="25" />
<StackPanel Orientation="Horizontal">
<Button x:Name="btnDelete" Margin="5 0 0 0" Content="Delete" Click="btnDelete_Click_1"></Button>
</StackPanel>
</StackPanel>
</UserControl>
和代码背后......
/// <summary>
/// Interaction logic for CatItem.xaml
/// </summary>
public partial class CatItem : UserControl
{
public CatItem()
{
InitializeComponent();
}
private void btnDelete_Click_1(object sender, RoutedEventArgs e)
{
if (DeleteClick != null)
DeleteClick(sender, e);
}
public event RoutedEventHandler DeleteClick;
}
从调用xaml,您可以使用此事件,如下所示。
<ItemsControl x:Name="itmsList" ItemsSource="{Binding Path=ModelListVMs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<uc:CatItem DeleteClick="ItemDeleteClick"></uc:CatItem> <!-- Using click here -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在窗口的背景中,您可以选择任何按钮的事件。
public void ItemDeleteClick(object sender, RoutedEventArgs e)
{
var ctx = (sender as Button);
//can get datacontext and other properties easily from here
}
对不起,这不是一个直接的答案,但希望它会帮助你朝着正确的方向发展。