Question

I have a listbox that is bound to a list of custom objects. I can get the listbox items to display correctly using the ListBox.ItemTemplate in xaml. The custom objects for the listbox are all of the same base class outlined below.

public class HomeViewMenuItem : UIElement
{
    private Uri _uri;
    private IRegionManager _manager;

    public HomeViewMenuItem(string text, Uri uri, IRegionManager manager)
    {
        this.PreviewMouseDown += HomeViewMenuItem_PreviewMouseDown;
        this.PreviewKeyDown += HomeViewMenuItem_PreviewKeyDown;
        _manager = manager;
        Text = text;
        _uri = uri;
        ClickCommand = new DelegateCommand(this.Click, this.CanClick);
    }

    void HomeViewMenuItem_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        if (e.Key == System.Windows.Input.Key.Enter)
        {
            e.Handled = true;
            this.ClickCommand.Execute();
        }
    }

    void HomeViewMenuItem_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        e.Handled = true;
        this.ClickCommand.Execute();
    }

    private void Click()
    {
        _manager.Regions[RegionNames.MainRegion].RequestNavigate(_uri);
    }

    private bool CanClick()
    {
        return true;
    }

    public DelegateCommand ClickCommand { get; set; }

    public string Text { get; set; }
}

The problem I am having is the HomeViewMenuItem_PreviewKeyDown method is not getting called. I believe this is because the method is getting called on the ListBoxItem itself first and getting handled there. I was able to verify this by obtaining a reference to the ListBoxItem object through listBox.ItemContainerGenerator.ContainerFromIndex(0) after the ItemContainerGenerator status changes to ContainersGenerated and adding an event handler there. This event handler correctly fired. Normally this would be an ok solution on a small project but I plan on having more listboxes with the same sort of functionality and would like to have a simpler/better solution. Is there a way that I can get my base class previewkeydown method to work?

The only solution I could think of is to have the base class inherit from ListBoxItem instead of UIElement then get the ListBox to create my items instead of ListBoxItems. But I dont think that is really possible without creating my own ListBox implementation.

Was it helpful?

Solution

You seem to be somewhat confused. In WPF, we create data items and declare DataTemplates to define what those items should look like in the UI. Our data items do not extend UI classes. If you have to handle the PreviewKeyDown event, then attach a handler to the UI element in the DataTemplate instead:

<DataTemplate>
    <Grid PreviewKeyDown="HomeViewMenuItem_PreviewKeyDown">
        ...
    </Grid>
</DataTemplate>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top