如何处理TextBlock使用prism 6在WPF中的网格控件中单击?

时间:2016-06-22 13:03:02

标签: c# .net wpf binding prism

我有一个场景,我向用户显示一个窗口,并要求他们通过左键单击选择任何内容。见附件pix enter image description here

所以在这个窗口中,我在Prism 6.1.0框架之后有相应的WindowViewModel。我想将此click事件绑定到Grid而不是每个TextBlock与Binding绑定。可能吗?

如果是,我试过这个。在网格控制我的代码就是这个。

    <Grid x:Name="Locals1">
    <Grid.InputBindings>
        <MouseBinding MouseAction="LeftClick"
        Gesture="LeftClick" Command="{Binding MouseCommand, 
        Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        CommandParameter="{Binding ElementName=Locals1, 
           Path=SelectedItem, Mode=TwoWay}"
     />
     </Grid.InputBindings>
<TextBlock Focusable="True" text="textblock1" />
<TextBlock Focusable="True" text="textblock2" />
<TextBlock Focusable="True" text="textblock3" />
<TextBlock Focusable="True" text="textblock4" />
</Grid>

在WindowViewModel中,我有一个像这样的代码。

public WindowViewModel(IEventAggregator eventAggregator)
{
    MouseCommand = new DelegateCommand<string>(OnConnection);
}

private void OnConnection(string obj)
    {
        ... 
    }

但是我没有在OnConnection方法中获得TextBlock.Text值。这真的太难了吗?我对WPF和MVVM的了解,我们可以在父控件本身处理子点击事件。这将减少重复代码。

我知道我做的事情肯定是错的。但我不知道到底是什么。如何将此值从WindowViewModel传递到MainWindowViewModel?

我可以在所有文本块中使用绑定来实现相同的功能,但这不符合Prism的目的。基本上所有文本块点击事件功能都相同,只是文本块的值会有所不同。

感谢

2 个答案:

答案 0 :(得分:1)

老实说,我不喜欢我的回答,但是:

您使用的是Grid,而不是DataGrid和类似内容,那么您在上下文中的SelectedItem是什么?!

在这种情况下,我无法发明如何使用漂亮的绑定,所以我改变了命令

public DelegateCommand<Object> MouseCommand { get; set; }

public WindowViewModel(IEventAggregator eventAggregator)
{
    MouseCommand = new DelegateCommand<object>(OnConnection);
}

private void OnConnection(object obj)
{
    var text = GetTextFromClickOnGrid(obj);
}

private string GetTextFromClickOnGrid(object obj)
{
    var grid = obj as Grid;
    if (grid != null)
    {
        var mousePos = Mouse.GetPosition(grid);
        var itemUnderMouse = VisualTreeHelper.HitTest(grid, mousePos);
        var textBlock = itemUnderMouse.VisualHit as TextBlock;
        if (textBlock != null)
        {
            return textBlock.Text;
        }
    }

    var textBlockUnderMouse = Mouse.DirectlyOver as TextBlock;
    if (textBlockUnderMouse != null)
    {
        return textBlockUnderMouse.Text;
    }

    return string.Empty;
}

和xaml

<Grid Grid.Row="1" x:Name="Locals1">
            <Grid.InputBindings>
                <MouseBinding MouseAction="LeftClick"
                              Gesture="LeftClick" 
                              Command="{Binding MouseCommand, 
                                                Mode=TwoWay,                            
                                        UpdateSourceTrigger=PropertyChanged}" 
                              CommandParameter="{Binding ElementName=Locals1}"
                 />
            </Grid.InputBindings>
            <TextBlock Focusable="True" Text="textblock1" Height="30" Width="100" Margin="115,45,302,84" />
            <TextBlock Focusable="True" Text="textblock2" Height="30" Width="100" Margin="115,10,302,119"/>
            <TextBlock Focusable="True" Text="textblock3" Height="30" Width="100" Margin="10,45,407,84"/>
            <TextBlock Focusable="True" Text="textblock4" Height="30" Width="100" Margin="10,10,407,119"/>

        </Grid>

答案 1 :(得分:-1)

我认为你这样看:

   <i:Interaction.Triggers>
        <i:EventTrigger EventName="LeftClick">
          <command:EventToCommand
            Command="{Binding Main.MouseCommand ,
              Mode=OneWay,
              Source={StaticResource Locator}}" />
        </i:EventTrigger>
      </i:Interaction.Triggers>

绑定你想要的东西。几乎任何命令的任何事件。

ViewModelLocator:

public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            SimpleIoc.Default.Register<MainViewModel>();
        }

        /// <summary>
        /// Gets the Main property.
        /// </summary>
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }
    }