如何在textBlock上设置on click效果并打开一个新的WPF窗口?

时间:2014-08-12 12:31:53

标签: c# wpf xaml

嗨,我是WPF的新手,我正在努力学习它。所以现在我想知道如何在ListBox中的文本块上创建onclick效果。我想点击listBox中的任何项目并打开一个新窗口。我一定是做错了什么但我不知道它是什么。到目前为止,我有以下内容。

<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>

上面的代码在我的XAML文件中。如果是这样,我还需要其他东西。它应该在哪里?

1 个答案:

答案 0 :(得分:3)

这是MVVM警察! ;)

Xaml:使用绑定到ICommand而不是System.Windows.Interactivity&amp; forinstance galasoft mvvm light。 我没有测试过下面的代码,我只是用记事本++编写了它。我现在看到一件事情,你是在一个数据模板&amp; listboxitem ...你的TextBlock会在LI而不是VM上查找命令,所以你需要一个时髦的绑定。检查它是否有效,但是您希望您的click事件在vm的datacontext上执行,而不是在listbox项上执行,因此必须稍微更改绑定(vacation ... =)) 列表框中的项目包装在ListBoxItems中,datacontext设置为LI应该呈现的内容,即列表中的项目。

您可能想要更改frpm

下面的KeyUp绑定
<command:EventToCommand Command="{Binding KeyUpCommand}" PassEventArgsToCommand="True"/> 

要:

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

确保将UserControl替换为您的控件/页面/ 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>

现在您将需要一个viewmodel,您将其设置为datacontext。这是一个简单基类的例子(扩展由galasoft提供的ViewModelBase以增加功能是很好的。

VM baseclass(简化):

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
    }
}

希望它有所帮助!在我们将由命令调用的方法中创建断点,并观察命令方法的输出和堆栈跟踪。

干杯

了Stian