简体   繁体   中英

How to set a on click effect on a textBlock and open a new WPF window?

Hi I am new to the WPF and I am trying to learn it. So now I want to know how to create an onclick effect on a textblock that is in ListBox. I want to click on any of the items in the listBox and open a new window. I must be doing something wrong but I cant figure out what is it. So far I have the following.

<Grid>
    <ItemsControl ItemsSource="{Binding Source={StaticResource cvsRoutes}}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Name}" MinHeight="50">
                    <ListBox>
                        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBox_MouseLeftButtonDown" />
                        <TextBlock Text="Something" >
                            <TextBlock.InputBindings>
                                <MouseBinding Command="" MouseAction="LeftClick" />
                            </TextBlock.InputBindings>
                        </TextBlock>
                        <TextBlock Text="Something" />
                        <TextBlock Text="Something" />
                        <TextBlock Text="Something" />
                        <TextBlock Text="Something" />
                    </ListBox>
                </Expander>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

The code above is in my XAML file. Do I need something else if so. Where should it be?

This is the MVVM police! ;)

Xaml: Use bindings to ICommand instead and System.Windows.Interactivity & forinstance galasoft mvvm light. I haven't tested the code below, I just wrote it in notepad++.. Ouch I see one thing here now, you are doing this inside a datatemplate & listboxitem... Your TextBlock will look for the command on the LI and not VM, so you need a funky binding here. Check if it works, but you want your click event to execute on the datacontext of the vm, and not the listbox item, so binding must be changed slightly (vacation... =) ) Items in a listbox is wrapped in ListBoxItems and the datacontext is set what the LI is supposed to present, an item in a list.

You might want to change the KeyUp binding below frpm

<command:EventToCommand Command="{Binding KeyUpCommand}" PassEventArgsToCommand="True"/> 

To:

<command:EventToCommand Command="{Binding Path=DataContext.KeyUpCommandCommand, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}}}"  PassEventArgsToCommand="True"/>

To be sure replace UserControl with the name of your control/page/cust ctrl/window.

...
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
xmlns:local="clr-namespace:YOURNAMSPACE"
...

<UserControl.DataContext>
    <local:ViewModelListStuff/>
</UserControl.DataContext>

<Grid>
    <ItemsControl ItemsSource="{Binding Source={StaticResource cvsRoutes}}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Name}" MinHeight="50">
                    <ListBox>                            
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                                <command:EventToCommand Command="{Binding PreviewMouseLeftButtonDownCommand}" PassEventArgsToCommand="True"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                        <TextBlock Text="Something" >
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="KeyUp">
                                    <command:EventToCommand Command="{Binding KeyUpCommand}" PassEventArgsToCommand="True"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </TextBlock>
                        <TextBlock Text="Something" />
                        <TextBlock Text="Something" />
                        <TextBlock Text="Something" />
                        <TextBlock Text="Something" />
                    </ListBox>
                </Expander>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

Now you are going to need a viewmodel, which you set as datacontext. Here is an example with a simple baseclass (It's nice to expand ViewModelBase provided by galasoft to add functionality.

VM baseclass (simplified):

public class SomeBaseClass : INotifyPropertyChanged
{
    // Other common functionality goes here..

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]// Commment out if your don't have R#
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

VM:

public class ViewModelListStuff : SomeBaseClass
{
    private string name;
    public ICommand PreviewMouseLeftButtonDownCommand { get; set; }
    public ICommand KeyUpCommand { get; set; }

    public String Name
    {
        get { return name; }
        set
        {
            if (value == name) return;
            name = value;
            OnPropertyChanged();
        }
    }

    // I would have exposed your cvsSomething here as a property instead, whatever it is.

    public ViewModelListStuff() 
    {
        InitStuff();
    }

    public void InitStuff()
    {
        PreviewMouseLeftButtonDownCommand = new RelayCommand<MouseButtonEventArgs>(PreviewMouseLeftButtonDown);
        KeyUpCommandnCommand = new RelayCommand<KeyEventArgs>(KeyUp);
    }

    private void KeyUp(KeyEventArgs e)
    {
        // Do your stuff here...
    }

    private void PreviewMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        // Do your stuff heere
    }
}

Hope it helps! Create a breakpoint in the methods which will we invoked by the commands and watch your output and stacktrace of the command methods.

Cheers

Stian

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM