C# wpf mvvm identify selected node in treeview with button click












0















I just want to identify the selected node on my treeview when I click button on my tree, please consider the image below:



enter image description here



Treeview is bound to viewmodel and I have a property to hold such value when you click the plus button the value for the selected node should be set. The only time that the selected value is set when you click on "sample node" first before you click the plus button. Below is the code for my xaml:



<TreeView x:Name="tree" ItemsSource="{Binding SectorTree, Mode=OneWay}" MinHeight="150">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=OneTime}">
<StackPanel Orientation="Horizontal">
<Button HorizontalAlignment="Center" Command="{Binding SelectedItemChangedCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ToolTip="Edit sector name" Background="Transparent" BorderThickness="0">
<Button.Content>
<Image Width="14" Height="14" Margin="0,0,0,0" Source="path_of_image" />
</Button.Content>
</Button>
<ContentPresenter Content="{Binding SectorName, Mode=OneTime}" Margin="2,0" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>









share|improve this question



























    0















    I just want to identify the selected node on my treeview when I click button on my tree, please consider the image below:



    enter image description here



    Treeview is bound to viewmodel and I have a property to hold such value when you click the plus button the value for the selected node should be set. The only time that the selected value is set when you click on "sample node" first before you click the plus button. Below is the code for my xaml:



    <TreeView x:Name="tree" ItemsSource="{Binding SectorTree, Mode=OneWay}" MinHeight="150">
    <TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=OneTime}">
    <StackPanel Orientation="Horizontal">
    <Button HorizontalAlignment="Center" Command="{Binding SelectedItemChangedCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    ToolTip="Edit sector name" Background="Transparent" BorderThickness="0">
    <Button.Content>
    <Image Width="14" Height="14" Margin="0,0,0,0" Source="path_of_image" />
    </Button.Content>
    </Button>
    <ContentPresenter Content="{Binding SectorName, Mode=OneTime}" Margin="2,0" />
    </StackPanel>
    </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
    <TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    </Style>
    </TreeView.ItemContainerStyle>
    </TreeView>









    share|improve this question

























      0












      0








      0








      I just want to identify the selected node on my treeview when I click button on my tree, please consider the image below:



      enter image description here



      Treeview is bound to viewmodel and I have a property to hold such value when you click the plus button the value for the selected node should be set. The only time that the selected value is set when you click on "sample node" first before you click the plus button. Below is the code for my xaml:



      <TreeView x:Name="tree" ItemsSource="{Binding SectorTree, Mode=OneWay}" MinHeight="150">
      <TreeView.ItemTemplate>
      <HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=OneTime}">
      <StackPanel Orientation="Horizontal">
      <Button HorizontalAlignment="Center" Command="{Binding SelectedItemChangedCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
      ToolTip="Edit sector name" Background="Transparent" BorderThickness="0">
      <Button.Content>
      <Image Width="14" Height="14" Margin="0,0,0,0" Source="path_of_image" />
      </Button.Content>
      </Button>
      <ContentPresenter Content="{Binding SectorName, Mode=OneTime}" Margin="2,0" />
      </StackPanel>
      </HierarchicalDataTemplate>
      </TreeView.ItemTemplate>
      <TreeView.ItemContainerStyle>
      <Style TargetType="{x:Type TreeViewItem}">
      <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
      </Style>
      </TreeView.ItemContainerStyle>
      </TreeView>









      share|improve this question














      I just want to identify the selected node on my treeview when I click button on my tree, please consider the image below:



      enter image description here



      Treeview is bound to viewmodel and I have a property to hold such value when you click the plus button the value for the selected node should be set. The only time that the selected value is set when you click on "sample node" first before you click the plus button. Below is the code for my xaml:



      <TreeView x:Name="tree" ItemsSource="{Binding SectorTree, Mode=OneWay}" MinHeight="150">
      <TreeView.ItemTemplate>
      <HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=OneTime}">
      <StackPanel Orientation="Horizontal">
      <Button HorizontalAlignment="Center" Command="{Binding SelectedItemChangedCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
      ToolTip="Edit sector name" Background="Transparent" BorderThickness="0">
      <Button.Content>
      <Image Width="14" Height="14" Margin="0,0,0,0" Source="path_of_image" />
      </Button.Content>
      </Button>
      <ContentPresenter Content="{Binding SectorName, Mode=OneTime}" Margin="2,0" />
      </StackPanel>
      </HierarchicalDataTemplate>
      </TreeView.ItemTemplate>
      <TreeView.ItemContainerStyle>
      <Style TargetType="{x:Type TreeViewItem}">
      <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
      </Style>
      </TreeView.ItemContainerStyle>
      </TreeView>






      c# wpf mvvm treeview






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jul 19 '18 at 19:47









      RobRob

      3882829




      3882829
























          2 Answers
          2






          active

          oldest

          votes


















          0














          This is how I solved the same problem in the Click event of the buttons in the TreeView.





          1. Add a 'Me' property to the MyNodeClass that is bound to each TreeView node:



            public object Me { get { return this; } }



          2. Bind the Tag property of the Button to Me:



            Button Tag="{Binding Me}" Click="Button_Click"



          3. Find the instance in the Button_Click(object sender...) event:



            MyNodeClass x = ((Button)sender).Tag as MyNodeClass







          share|improve this answer
























          • or just Button Tag="{Binding}"

            – Peregrine
            Nov 23 '18 at 11:54



















          0














          It's not clear what problem you're trying to solve by adding this button to the TreeView data template.



          The TreeView already has a SelectedItemChanged event, and a SelectedItem property.



          The alternative is to use a Behavior to add a new bindable BoundSelectedItem property to the Treeiew. This will return the data item class, not a TreeViewItem instance.



          public class perTreeViewHelper : Behavior<TreeView>
          {
          public object BoundSelectedItem
          {
          get => GetValue(BoundSelectedItemProperty);
          set => SetValue(BoundSelectedItemProperty, value);
          }

          public static readonly DependencyProperty BoundSelectedItemProperty =
          DependencyProperty.Register("BoundSelectedItem",
          typeof(object),
          typeof(perTreeViewHelper),
          new FrameworkPropertyMetadata(null,
          FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
          OnBoundSelectedItemChanged));

          private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
          {
          if (args.NewValue is perTreeViewItemViewModelBase item)
          item.IsSelected = true;
          }

          protected override void OnAttached()
          {
          base.OnAttached();
          AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
          }

          protected override void OnDetaching()
          {
          AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
          base.OnDetaching();
          }

          private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
          {
          BoundSelectedItem = args.NewValue;
          }
          }


          More details on my recent blog post.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51430690%2fc-sharp-wpf-mvvm-identify-selected-node-in-treeview-with-button-click%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            This is how I solved the same problem in the Click event of the buttons in the TreeView.





            1. Add a 'Me' property to the MyNodeClass that is bound to each TreeView node:



              public object Me { get { return this; } }



            2. Bind the Tag property of the Button to Me:



              Button Tag="{Binding Me}" Click="Button_Click"



            3. Find the instance in the Button_Click(object sender...) event:



              MyNodeClass x = ((Button)sender).Tag as MyNodeClass







            share|improve this answer
























            • or just Button Tag="{Binding}"

              – Peregrine
              Nov 23 '18 at 11:54
















            0














            This is how I solved the same problem in the Click event of the buttons in the TreeView.





            1. Add a 'Me' property to the MyNodeClass that is bound to each TreeView node:



              public object Me { get { return this; } }



            2. Bind the Tag property of the Button to Me:



              Button Tag="{Binding Me}" Click="Button_Click"



            3. Find the instance in the Button_Click(object sender...) event:



              MyNodeClass x = ((Button)sender).Tag as MyNodeClass







            share|improve this answer
























            • or just Button Tag="{Binding}"

              – Peregrine
              Nov 23 '18 at 11:54














            0












            0








            0







            This is how I solved the same problem in the Click event of the buttons in the TreeView.





            1. Add a 'Me' property to the MyNodeClass that is bound to each TreeView node:



              public object Me { get { return this; } }



            2. Bind the Tag property of the Button to Me:



              Button Tag="{Binding Me}" Click="Button_Click"



            3. Find the instance in the Button_Click(object sender...) event:



              MyNodeClass x = ((Button)sender).Tag as MyNodeClass







            share|improve this answer













            This is how I solved the same problem in the Click event of the buttons in the TreeView.





            1. Add a 'Me' property to the MyNodeClass that is bound to each TreeView node:



              public object Me { get { return this; } }



            2. Bind the Tag property of the Button to Me:



              Button Tag="{Binding Me}" Click="Button_Click"



            3. Find the instance in the Button_Click(object sender...) event:



              MyNodeClass x = ((Button)sender).Tag as MyNodeClass








            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 23 '18 at 11:46









            PeterEPeterE

            11




            11













            • or just Button Tag="{Binding}"

              – Peregrine
              Nov 23 '18 at 11:54



















            • or just Button Tag="{Binding}"

              – Peregrine
              Nov 23 '18 at 11:54

















            or just Button Tag="{Binding}"

            – Peregrine
            Nov 23 '18 at 11:54





            or just Button Tag="{Binding}"

            – Peregrine
            Nov 23 '18 at 11:54













            0














            It's not clear what problem you're trying to solve by adding this button to the TreeView data template.



            The TreeView already has a SelectedItemChanged event, and a SelectedItem property.



            The alternative is to use a Behavior to add a new bindable BoundSelectedItem property to the Treeiew. This will return the data item class, not a TreeViewItem instance.



            public class perTreeViewHelper : Behavior<TreeView>
            {
            public object BoundSelectedItem
            {
            get => GetValue(BoundSelectedItemProperty);
            set => SetValue(BoundSelectedItemProperty, value);
            }

            public static readonly DependencyProperty BoundSelectedItemProperty =
            DependencyProperty.Register("BoundSelectedItem",
            typeof(object),
            typeof(perTreeViewHelper),
            new FrameworkPropertyMetadata(null,
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            OnBoundSelectedItemChanged));

            private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
            {
            if (args.NewValue is perTreeViewItemViewModelBase item)
            item.IsSelected = true;
            }

            protected override void OnAttached()
            {
            base.OnAttached();
            AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
            }

            protected override void OnDetaching()
            {
            AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
            base.OnDetaching();
            }

            private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
            {
            BoundSelectedItem = args.NewValue;
            }
            }


            More details on my recent blog post.






            share|improve this answer




























              0














              It's not clear what problem you're trying to solve by adding this button to the TreeView data template.



              The TreeView already has a SelectedItemChanged event, and a SelectedItem property.



              The alternative is to use a Behavior to add a new bindable BoundSelectedItem property to the Treeiew. This will return the data item class, not a TreeViewItem instance.



              public class perTreeViewHelper : Behavior<TreeView>
              {
              public object BoundSelectedItem
              {
              get => GetValue(BoundSelectedItemProperty);
              set => SetValue(BoundSelectedItemProperty, value);
              }

              public static readonly DependencyProperty BoundSelectedItemProperty =
              DependencyProperty.Register("BoundSelectedItem",
              typeof(object),
              typeof(perTreeViewHelper),
              new FrameworkPropertyMetadata(null,
              FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
              OnBoundSelectedItemChanged));

              private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
              {
              if (args.NewValue is perTreeViewItemViewModelBase item)
              item.IsSelected = true;
              }

              protected override void OnAttached()
              {
              base.OnAttached();
              AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
              }

              protected override void OnDetaching()
              {
              AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
              base.OnDetaching();
              }

              private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
              {
              BoundSelectedItem = args.NewValue;
              }
              }


              More details on my recent blog post.






              share|improve this answer


























                0












                0








                0







                It's not clear what problem you're trying to solve by adding this button to the TreeView data template.



                The TreeView already has a SelectedItemChanged event, and a SelectedItem property.



                The alternative is to use a Behavior to add a new bindable BoundSelectedItem property to the Treeiew. This will return the data item class, not a TreeViewItem instance.



                public class perTreeViewHelper : Behavior<TreeView>
                {
                public object BoundSelectedItem
                {
                get => GetValue(BoundSelectedItemProperty);
                set => SetValue(BoundSelectedItemProperty, value);
                }

                public static readonly DependencyProperty BoundSelectedItemProperty =
                DependencyProperty.Register("BoundSelectedItem",
                typeof(object),
                typeof(perTreeViewHelper),
                new FrameworkPropertyMetadata(null,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                OnBoundSelectedItemChanged));

                private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
                {
                if (args.NewValue is perTreeViewItemViewModelBase item)
                item.IsSelected = true;
                }

                protected override void OnAttached()
                {
                base.OnAttached();
                AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
                }

                protected override void OnDetaching()
                {
                AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
                base.OnDetaching();
                }

                private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
                {
                BoundSelectedItem = args.NewValue;
                }
                }


                More details on my recent blog post.






                share|improve this answer













                It's not clear what problem you're trying to solve by adding this button to the TreeView data template.



                The TreeView already has a SelectedItemChanged event, and a SelectedItem property.



                The alternative is to use a Behavior to add a new bindable BoundSelectedItem property to the Treeiew. This will return the data item class, not a TreeViewItem instance.



                public class perTreeViewHelper : Behavior<TreeView>
                {
                public object BoundSelectedItem
                {
                get => GetValue(BoundSelectedItemProperty);
                set => SetValue(BoundSelectedItemProperty, value);
                }

                public static readonly DependencyProperty BoundSelectedItemProperty =
                DependencyProperty.Register("BoundSelectedItem",
                typeof(object),
                typeof(perTreeViewHelper),
                new FrameworkPropertyMetadata(null,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                OnBoundSelectedItemChanged));

                private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
                {
                if (args.NewValue is perTreeViewItemViewModelBase item)
                item.IsSelected = true;
                }

                protected override void OnAttached()
                {
                base.OnAttached();
                AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
                }

                protected override void OnDetaching()
                {
                AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
                base.OnDetaching();
                }

                private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
                {
                BoundSelectedItem = args.NewValue;
                }
                }


                More details on my recent blog post.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 23 '18 at 12:07









                PeregrinePeregrine

                2,38721230




                2,38721230






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51430690%2fc-sharp-wpf-mvvm-identify-selected-node-in-treeview-with-button-click%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    404 Error Contact Form 7 ajax form submitting

                    How to know if a Active Directory user can login interactively

                    TypeError: fit_transform() missing 1 required positional argument: 'X'