2

コンボボックスのカスタム ドロップダウンまたはポップアップ テンプレートでいくつかのイベントを接続する際に問題が発生しています。

ところで、このカスタム テンプレートは IE 10 のテンプレートのように見え ここに画像の説明を入力 ます。しかし、履歴リストのアイテムを削除するのに問題があります。以下は私の PART_Popup テンプレートです

<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 エラーを返しています

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が見つからない行。

どうすればこれを解決できますか?

- アップデート -

lb.Loaded += (a, b) =>
{
    Button btnDeleteHistoryItem = (Button)lb.Template.FindName("btnDeleteHistoryItem", lb);
    //if (btnDeleteHistoryItem != null)
    {
        btnDeleteHistoryItem.Click += DeleteHistoryItem_Click;
    }
};

どちらも機能しません

4

1 に答える 1

2

ここでは、コマンドを使用するのがおそらく最も簡単な解決策です。コマンドを削除ボタンにフックして、現在のアイテムをパラメーターとして渡すことができます。説明する簡単なサンプルを次に示します。

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()));
    }
}

コンボボックスのバインディングは次のようになります。

<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 のコマンド バインディングを調整するだけです。それが役立つことを願っています!

于 2013-02-05T02:41:36.180 に答える