0

I want to find the parent of usercontrol from Markup, I used the following code

var hostRoot = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
var host = hostRoot.RootObject;

var do = host as DependencyObject;
var uc = do as UserControl;
var ucParent = uc.Parent;

and

var wp = Window.GetWindow(uc);

But both return null

Update:

<Window x:Class="WpfApp12.MainWindow">
    <Grid>
       <local:UserControl1/>
    </Grid>
</Window>

and

<UserControl x:Class="WpfApp12.UserControl1">
    <StackPanel>
       
        <TextBlock Text="{me:myMarkup}"/>

    </StackPanel>
</UserControl>

Update 2:

this is my Markup

public class myMarkup : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var hostRoot = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
            var host = hostRoot.RootObject;
            var xv = host as DependencyObject;

            var ww = Window.GetWindow(xv);
            return null;
        }
    }

Update 3: sample project

https://github.com/ghost1372/HandyControls/files/6259944/WpfApp18.zip

hadi khodabandeh
  • 585
  • 2
  • 7
  • 20
  • I wouldn't use `do` as variable name as this is a C# keyword. On to the question, what is your `uc` set to? Because if the parent is null then it suggests the user control hasn't been added to the element tree. – ekke Apr 05 '21 at 18:17
  • Forget naming This is just an example, Usercontrol is inside Window – hadi khodabandeh Apr 05 '21 at 18:19
  • In that case could you provide a minimum reproducible example? Because if the user control has been added to the logical tree then the parent should be set. – ekke Apr 05 '21 at 18:21
  • @ekke i updated my question Is it enough or do I have to upload a project? – hadi khodabandeh Apr 05 '21 at 18:22
  • Does this help https://stackoverflow.com/questions/5000228/how-can-you-get-the-parent-of-a-uielement ? – Serg Apr 05 '21 at 18:25
  • 1
    I don't think there's anything obviously wrong with your code that I can see. Uploading a sample project would probably help. – ekke Apr 05 '21 at 18:28
  • @ekke i uploaded a sample project – hadi khodabandeh Apr 05 '21 at 18:36
  • @Serg no not work – hadi khodabandeh Apr 05 '21 at 18:41
  • 1
    Hey so it looks like you're trying to access the logical tree before `InitializeComponent` has completed. `InitializeComponent` builds the logical tree up including initialising the parent from the XAML. You won't be able to access this like this. If you can explain what you're trying to do, perhaps it's possible to achieve it another way? – ekke Apr 05 '21 at 18:44
  • My markup is a bit complicated and i wrote it for localization, Provider property is registered in Windows, so I need to have access to Windows to be able to read Provider – hadi khodabandeh Apr 05 '21 at 18:49
  • 1
    @ekke i used Application.Current.MainWindow Not too good, but not too bad – hadi khodabandeh Apr 05 '21 at 18:58

1 Answers1

1

You need to wait until the UserControl has been loaded before calling Window.GetWindow:

public class myMarkup : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var hostRoot = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
        var host = hostRoot.RootObject;
        var xv = host as FrameworkElement;

        //local function:
        void OnLoaded(object sender, RoutedEventArgs e)
        {
            FrameworkElement xv = (FrameworkElement)sender;
            Window parentWindow = Window.GetWindow(xv);
            //do something with the window...
        }

        Window parentWindow;
        if (xv.IsLoaded)
        {
            parentWindow = Window.GetWindow(xv);
            //do something with the window...
        }
        else
        {
            xv.Loaded += OnLoaded;
        }

        return null;
    }
}
mm8
  • 163,881
  • 10
  • 57
  • 88