Question

So I have a WPF UserControl:

<UserControl x:Class="BI_Builder.Views.ObjectTreeView"
             x:Name="UC1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:BI_Builder"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
                 xmlns:viewModels="clr-namespace:BI_Builder.ViewModels"
             xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding}">

    <UserControl.Resources>
        <ContentControl x:Key="Context" Content="{Binding}" />

        <DataTemplate x:Key="DataSourceTemplate">
            <TextBlock Text="{Binding Path=Name}" >
     <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <command:EventToCommand Command="{Binding Path=DataContext.OpenCommand, Mode=OneWay,ElementName=UC1}"                />
                </i:EventTrigger>
            </i:Interaction.Triggers>
               </TextBlock>
        </DataTemplate>

        <HierarchicalDataTemplate x:Key="ItemTemplate"
                                          ItemsSource="{Binding Children}"
                                          ItemTemplate="{StaticResource DataSourceTemplate}">
            <StackPanel>
                <TextBlock Text="{Binding Header}">
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate> 
    </UserControl.Resources>


    <Grid>
        <TreeView Name="TreeView" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemTemplate}" >
        </TreeView>
    </Grid>
</UserControl>

And here's the main view model for the user control:

public class ObjectTreeViewModel : ObservableObject       {

        public  ObservableCollection<ItemViewModel> Items  {
            get {
                if (_items != null) return _items;
                _items =  new ObservableCollection<ItemViewModel>();
                _items.Add(DataSources);
                return _items;

            }
            set { _items = value;
            }
        }

        public ItemViewModel DataSources {
            get { return _dataSources ?? (_dataSources = new ItemViewModel() { Header = "Data Sources", Children = new ObservableCollection<object>(DataSourceList) }); }
            set { _dataSources = value; }
        }

        public List<DataSource> DataSourceList;

        public ICommand OpenCommand    {
            get { if (_openCommand == null) { return _openCommand = new RelayCommand(OpenDataSource); } return _openCommand; }

        }

        private void OpenDataSource()           {
            MessageBox.Show("Test");
        }

        public ObjectTreeViewModel()      {
             DataSourceList = new List<DataSource>();
                DataSourceList.Add(new DataSource() { Name = "Test" });
        }


        private ItemViewModel _dataSources;
        private ObservableCollection<ItemViewModel> _items;
        private RelayCommand _openCommand;
    }
}

I've tried every method I've come across on the web to get the EventToCommand in the DataSourceTemplate DataTemplate to fire. In fact, I'm pretty sure it knows where the OpenCommand is, because if I change the Path to gobbledygook, the Output window throws me an error saying that "ObjectTreeView" (which is the instance of the ObjectTreeViewModel view model being bound to the UserControl) doesn't have the gobbledygook property. So I think I've set the DataContext correctly ...

But whenever I click on the text blocks ... nothing.

Really trying to avoid code-behind (it just feels wrong), and full disclosure, I'm using MVVM Light's EventToCommand but not the full toolkit, although I'm tempted to rewrite what I have so far in it to see if using the Service Locator will solve this problem.

Était-ce utile?

La solution

The TextBlock control does not have a Click event. See MSDN.

You should use the MouseLeftButtonDown event instead:

<i:EventTrigger EventName="MouseLeftButtonDown">
   <!-- ... -->
</i:EventTrigger>

Autres conseils

Can you put a hyperlink inside your textblock instead and bind the command to the hyperlink? Note you can style the hyperlink to look like a plain textblock if needed.

<TextBlock>
     <Hyperlink Command="{Binding Path=DataContext.OpenCommand" Text="{Binding Path=Name}" />
</TextBlock>

Also make sure that the ObjectTreeView class is instantiated and loaded into DataContext of the usercontrol.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top