简体   繁体   中英

How to handle the TextBlock Click within the Grid Control in WPF using prism 6?

I am having an scenario where I show a window to the user and ask them to choose anything by left click on it. See attached pix 在此处输入图片说明

So in this Window I have corresponding WindowViewModel following a Prism 6.1.0 framework. I want to bind this click event to the Grid instead of Binding with the each TextBlock each. Is it possible?

if yes, I tried this. In the grid Control my code is this.

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

And in the WindowViewModel I have a code like this.

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

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

But I don't get the TextBlock.Text value in that OnConnection method. Is it really so tough? What I know about WPF and MVVM that we can handle the child click event in the parent control itself. This will reduce duplicate codes.

I know I am doing something definitely wrong. But I don't know what exactly. How can I pass this value from WindowViewModel to the MainWindowViewModel?

I can achieve the same functionality using a binding each in all the textblocks but that will not serve the purpose of Prism. basically all the text Block click events functionality is same only the value of the textblock will be different.

thanks

Honestly, i don't like my answer, but:

You use Grid , not DataGrid and similar, so what is SelectedItem in you context?!

I cant invent how to use pretty binding in this case, so i changed command

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

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

and

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

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

i think you looking this:

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

binding what you want. Any event to almost any command.

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

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