问题描述
我在我的组合框中的自定义下拉列表或弹出模板中连接某些事件时遇到问题.
I am having a problem hooking up some events in my custom dropdown or Popup template in my combobox.
顺便说一下,这个自定义模板看起来像 IE 10 中的模板.这是图片我得到了部分外观(下面是我的).但是我在删除历史列表中的项目时遇到问题.下面是我的 PART_Popup 模板
This custom template by the way looks like the one in IE 10. Here's the pictureI got the partial look (the one below is mine). But I'm having a problem deleting an item in history list. Below is my PART_Popup template
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" MinWidth="{Binding ActualWidth, ElementName=Placement}">
<Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<!--<ScrollViewer>-->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel>
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Border Padding="5">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="History" Foreground="{StaticResource SeparatorLine}" />
<Border Height="2" Grid.Column="1" Margin="5,0,0,0" BorderBrush="{StaticResource SeparatorLine}" BorderThickness="0.5" />
</Grid>
<ListBox x:Name="listHistory" BorderThickness="0" Margin="0" Padding="0" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding }" />
<Button Grid.Column="1" HorizontalAlignment="Right" x:Name="btnDeleteHistoryItem" Content="r" FontFamily="Marlett" Style="{DynamicResource ButtonStyle}" Visibility="Hidden" Opacity="0.75" />
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Visibility" TargetName="btnDeleteHistoryItem" Value="Visible" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Border>
</StackPanel>
<Border Grid.Row="1" BorderBrush="{StaticResource SeparatorLine}" BorderThickness="0,1,0,0" Padding="5" Height="30">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#33000000" Offset="0"/>
<GradientStop Offset="1"/>
<GradientStop Offset="0.375"/>
</LinearGradientBrush>
</Border.Background>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="btnClearHistory" Content=" Clear History " Style="{DynamicResource ButtonStyle}" />
</StackPanel>
</Border>
</Grid>
<!--</ScrollViewer>-->
</Border>
</Themes:SystemDropShadowChrome>
</Popup>
好的,在 Listbox(listHistory) 中,我有一个名为 btnDeleteHistoryItem 的按钮,但我无法勾住它.它在我的代码中返回 Null 错误
alright, in the Listbox(listHistory) I have a button there called btnDeleteHistoryItem and I cannot hook it. It's returning a Null error in my code here
protected override void OnSourceInitialized(EventArgs e)
{
ListBox lb = (ListBox)cbSearch.Template.FindName("listHistory", cbSearch);
lb.ItemsSource = this.SearchHistory;
lb.SelectionChanged += cbResults_SelectionChanged;
Button btnDeleteHistoryItem = (Button)lb.Template.FindName("btnDeleteHistoryItem", lb);
// if (btnDeleteHistoryItem != null)
{
btnDeleteHistoryItem.Click += DeleteHistoryItem_Click;
}
// or --------------
Button btnDeleteHistoryItem = (Button)cbSearch.Template.FindName("btnDeleteHistoryItem", cbSearch);
// if (btnDeleteHistoryItem != null)
{
btnDeleteHistoryItem.Click += DeleteHistoryItem_Click;
}
}
这里的编码有点经典,所以没有在挂钩事件中实现 MVVM.所以问题是这个 Button btnDeleteHistoryItem = (Button)lb.Template.FindName("btnDeleteHistoryItem", lb); 或 Button btnDeleteHistoryItem = (Button)cbSearch.Template.FindName("btnDeleteHistoryItem", cbSearch);找不到 btnDeleteHistoryItem 的行.
Coding is a little classic here, so no MVVM implemented in hooking with events. So the problem is this Button btnDeleteHistoryItem = (Button)lb.Template.FindName("btnDeleteHistoryItem", lb); or Button btnDeleteHistoryItem = (Button)cbSearch.Template.FindName("btnDeleteHistoryItem", cbSearch); line where it cannot find that btnDeleteHistoryItem.
我该如何解决这个问题?
How can I resolve this?
-- 更新 --
lb.Loaded += (a, b) =>
{
Button btnDeleteHistoryItem = (Button)lb.Template.FindName("btnDeleteHistoryItem", lb);
//if (btnDeleteHistoryItem != null)
{
btnDeleteHistoryItem.Click += DeleteHistoryItem_Click;
}
};
也不行
推荐答案
在这里使用命令可能是最简单的解决方案.您可以将命令连接到删除按钮,并将当前项目作为参数传入.这是一个简单的示例来说明.
Using a command will probably be the easiest solution here. You can hook a command up to your delete buttons and pass the current item in as the parameter. Here's a simple sample to illustrate.
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
SomeCommand = new MySampleCommand();
cbo.Items.Add("Hello");
cbo.Items.Add("Item 1");
cbo.Items.Add("Another Item");
cbo.Items.Add("Something else");
cbo.Items.Add("Yet another item");
}
public MySampleCommand SomeCommand { get; set; }
}
public class MySampleCommand : ICommand {
public bool CanExecute(object parameter) {
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter) {
MessageBox.Show(string.Format("You are trying to remove {0}", parameter.ToString()));
}
}
您的组合框绑定看起来像:
Your combobox binding would look something like:
<Window x:Class="SOComboWithEmbeddedButton2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="ListBoxItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" />
<Button Command="{Binding SomeCommand, ElementName=Window}" CommandParameter="{Binding}" Content="Remove" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ComboBox ItemTemplate="{StaticResource ListBoxItemTemplate}" x:Name="cbo" />
</StackPanel>
只需调整 DataTemplate 上的 Command 绑定以指向具有您的命令对象实例的适当对象.希望有帮助!
Just adjust the Command binding on the DataTemplate to point to the appropriate object that has an instance of your command object. Hope that helps!
这篇关于带有自定义下拉(弹出)模板等的组合框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!