получение элемента управления из viewModel - PullRequest
2 голосов
/ 01 августа 2011

в моей viewModel я могу получить окно, связанное с ним, используя

var windows = Application.Current.Windows;
            for (var i = 0; i < windows.Count; i++)
            {
                if (windows[i].DataContext == this)
                {
                   //                      
                }
            }

в этом окне есть FlowDocument, и мне нужна ссылка на него здесь, в моей viewModel, я знаю, что когда-нибудь смогу нарушить правила и написать какой-то код позади, но так как у меня есть окно, и этот элемент управления содержится / child В этом окне я думал, что смогу сделать это без какого-либо кода, какие-либо предложения?

спасибо заранее

1 Ответ

1 голос
/ 01 августа 2011

Прежде всего, вы не используете MVVM правильно, если вам нужен доступ к элементам пользовательского интерфейса во ViewModel.Вместо этого вам следует рассмотреть возможность использования привязок (независимо от того, что вы делаете: -)

В любом случае, вы можете пройти по визуальному дереву, чтобы найти потомков Window.Однако FlowDocument отсутствует в визуальном дереве, так как FrameworkContentElement, поэтому VisualTreeHelper не будет работать.

Вам нужно будет объединить VisualTreeHelper и LogicalTreeHelper: реализацияэто можно найти здесь: Найти элемент по визуальному дереву

Вот его слегка переписанная версия, используйте его как

if (windows[i].DataContext == this)
{
    var flowDocument = windows[i].FindChild<FlowDocument>();
}

DependencyObjectExtensions.CS

public static class DependencyObjectExtensions
{
    public static T FindChild<T>(this DependencyObject source) where T : DependencyObject
    {
        if (source != null)
        {
            var childs = GetChildObjects(source);
            foreach (DependencyObject child in childs)
            {
                //analyze if children match the requested type
                if (child != null && child is T)
                {
                    return (T)child;
                }

                T descendant = FindChild<T>(child);
                if (descendant is T)
                {
                    return descendant;
                }
            }
        }
        return null;
    }
    public static IEnumerable<DependencyObject> GetChildObjects(this DependencyObject parent)
    {
        if (parent == null) yield break;

        if (parent is ContentElement || parent is FrameworkElement)
        {
            //use the logical tree for content / framework elements
            foreach (object obj in LogicalTreeHelper.GetChildren(parent))
            {
                var depObj = obj as DependencyObject;
                if (depObj != null) yield return (DependencyObject)obj;
            }
        }
        else
        {
            //use the visual tree per default
            int count = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < count; i++)
            {
                yield return VisualTreeHelper.GetChild(parent, i);
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...