【问题标题】:How to set a on click effect on a textBlock and open a new WPF window?如何在 textBlock 上设置点击效果并打开一个新的 WPF 窗口?
【发布时间】:2014-08-12 12:31:53
【问题描述】:

您好,我是 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 文件中。如果需要,我还需要其他东西吗?应该在哪里?

【问题讨论】:

标签: c# wpf xaml


【解决方案1】:

这是 MVVM 警察! ;)

Xaml:使用绑定到 ICommand 和 System.Windows.Interactivity & forinstance galasoft mvvm light。 我还没有测试下面的代码,我只是用 notepad++ 编写的。。 哎呀,我现在在这里看到一件事,您正在数据模板和列表框项中执行此操作...您的 TextBlock 将寻找命令在 LI 而不是 VM 上,所以你需要一个时髦的绑定。检查它是否有效,但是您希望单击事件在 vm 的数据上下文上执行,而不是在列表框项上执行,因此必须稍微更改绑定(假期...=)) 列表框中的项目被包装在 ListBoxItems 中,并且数据上下文被设置为 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>

现在您将需要一个视图模型,将其设置为数据上下文。这是一个简单基类的示例(很高兴扩展galasoft提供的ViewModelBase以添加功能。

VM 基类(简化):

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

虚拟机:

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

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

干杯

斯蒂安

【讨论】:

  • 您好,谢谢您的回答,我遇到了一些麻烦。我收到此错误命令:未找到 EventToCommand!这是为什么呢?
  • 重复:stackoverflow.com/questions/25280047/… 。您缺少对 Galasoft MVVM Light 的引用,请使用 nuget 并将其添加到那里或手动从 codeplex 下载。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-25
相关资源
最近更新 更多