1

I need to know when a parent in the VisualTree or LogicalTree changes of a Control. I need this feature, since anytime a parent changes I need to reevaluate the controls' window class, so that I can attached Command- and InputBindings.

I have a dirty way, which means I need to attach to each parent element and check for parent changes with events, but I was hoping there is another solution.

Example:

I have a UserControl

    <UserControl x:Class="WpfApplication21.UserControl1">
    <UserControl.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Cut" Executed="SomeHandler"></CommandBinding>
    </UserControl.CommandBindings>
</UserControl>

and I have a Window that contains one or many UserControls

<Window x:Class="WpfApplication21.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication21"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.New" Executed="SomeHandler"></CommandBinding>
    </Window.CommandBindings>
    <StackPanel>
        <local:UserControl1></local:UserControl1>
        <local:UserControl1></local:UserControl1>
    </StackPanel>
</Window>

Although in the example I have put the same command, it's only here to show in the example. In reality each control has different commands. The commands of each UserControl need to be merged into the CommandBindings of the Window (the same is true for InputBindings - not shown here). Each UserControl is a plugin that is created from a ViewModel dynamically, so each ViewModel has a different View (the example only shows UserControls, but in reality these a derivation from a UserControl).

For that reason I created a behavior that attaches to a CommandProvider that is implemented by the ViewModel (created by me) so that it's done without code-behind.

Since I have many ViewModels and therefore also Views I need to manage the Command-/InputBindings and attach them to the Window. One problem is that not every View can get a Focus, and somehow for UserControl event if they are focused the Command-/InputBindings don't work.

Is it a little clearer now? I now the situation is a bit complex.

msedi
  • 1,437
  • 15
  • 25
  • There is no built-in way because this is not normally a required (desired) feature. You want it because you are violating the Single Responsibility rule. The best approach is probably to redesign to something simpler. – H H Jan 09 '17 at 11:38
  • @HenkHolterman i cant get the question clearly, can you explain it ? btw @ O. R. Mapper im not the downvoter – WPFUser Jan 09 '17 at 11:40
  • "I need to know when a parent in the VisualTree or LogicalTree changes of a Control." i cant get this. – WPFUser Jan 09 '17 at 11:44
  • @HenkHolterman cool, msedi tried his best in the question, based on your comment, i thought you understood the question clearly and you wouldn't mind spending two minutes..my bad.. – WPFUser Jan 09 '17 at 12:05
  • You are right. I have added some examples, maybe we can discuss this a bit better now? – msedi Jan 09 '17 at 12:11
  • 1
    @HenkHolterman: "You want it because you are violating the Single Responsibility rule." - some 1.5 years ago, I have asked a similar question: [*Capture Changes to Parent Visual Tree*](http://stackoverflow.com/questions/31187522/capture-changes-to-parent-visual-tree). It describes a use case for which I required that behaviour. – O. R. Mapper Jan 09 '17 at 12:18
  • @O.R. Mapper: In some way you are right. In most of my cases there is almost no static WPF where I can define scopes since the controls are created and attached dynamically. I need to think a little bit about your solution. – msedi Jan 09 '17 at 12:35

1 Answers1

3

I have a dirty way, which means I need to attach to each parent element and check for parent changes with events, but I was hoping there is another solution.

Sorry to disappoint you but there is no other way, i.e. there is no "AnyParentChanged" event or something that you can hook up to.

You need to somehow iterate through all parent elements and hook up an event handler to an appropriate event for each one of them. It's either this or reconsider your entire approach.

Depending on whether a parent in the visual tree "changes" may not be the best way to solve whatever you are trying to do.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • "Depending on whether a parent in the visual tree "changes" may not be the best way". Maybe you are right, but I'm trying to attach my CommandBinding of the child element to the Window, since I want to have all Commands bundled at one place and I cannot focus the control. If there's a better way to locate my command, feel free to direct me ;-) I'm really searching for a better way. – msedi Jan 09 '17 at 11:41
  • 1
    You haven't posted any code snippets so it's hard to know what you are trying to do exactly but one way could be to be bind to an ICommand property of the parent window, i.e. all child elements bind to the very same command. – mm8 Jan 09 '17 at 11:45