Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 从viewModel获取控件_.net_Wpf_Mvvm_Parent Child - Fatal编程技术网

.net 从viewModel获取控件

.net 从viewModel获取控件,.net,wpf,mvvm,parent-child,.net,Wpf,Mvvm,Parent Child,在我的viewModel中,我可以使用 var windows = Application.Current.Windows; for (var i = 0; i < windows.Count; i++) { if (windows[i].DataContext == this) { //

在我的viewModel中,我可以使用

var windows = Application.Current.Windows;
            for (var i = 0; i < windows.Count; i++)
            {
                if (windows[i].DataContext == this)
                {
                   //                      
                }
            }
var-windows=Application.Current.windows;
对于(var i=0;i
这个窗口中有一个FlowDocument,我需要在我的viewModel中引用它,我知道有时我可以打破规则并编写一些代码,但是由于我有这个窗口,并且这个控件包含在这个窗口中,我想我可以在没有任何代码的情况下完成它,有什么建议吗


首先,如果您需要访问ViewModel中的UI元素,那么您使用MVVM的方式并不正确。你应该考虑使用绑定来代替这个(无论你在做什么:-)/P> 无论如何,您可以遍历可视化树以查找
窗口的子体。但是,
FlowDocument
不在可视化树中,因为它是一个
FrameworkContentElement
,因此
VisualTreeHelper
不起作用

您需要将
VisualTreeHelper
LogicalTreeHelper
结合起来:可以在此处找到此功能的实现:

这里是它的一个稍微重写的版本,像这样使用它

if (windows[i].DataContext == this)
{
    var flowDocument = windows[i].FindChild<FlowDocument>();
}
if(windows[i].DataContext==this)
{
var flowDocument=windows[i].FindChild();
}
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);
            }
        }
    }
}
公共静态类DependencyObjectExtensions
{
公共静态T FindChild(此DependencyObject源),其中T:DependencyObject
{
如果(源!=null)
{
var childs=GetChildObjects(源);
foreach(子对象中的DependencyObject子对象)
{
//分析子项是否与请求的类型匹配
if(child!=null&&child为T)
{
返回(T)儿童;
}
T后代=FindChild(child);
if(后代是T)
{
返回后代;
}
}
}
返回null;
}
公共静态IEnumerable GetChildObjects(此DependencyObject父对象)
{
如果(父项==null)产量中断;
if(父元素为ContentElement | |父元素为FrameworkElement)
{
//对内容/框架元素使用逻辑树
foreach(LogicalTreeHelper.GetChildren(父)中的对象obj)
{
var depObj=obj作为DependencyObject;
如果(depObj!=null)产生返回(DependencyObject)对象;
}
}
其他的
{
//默认情况下使用可视树
int count=VisualTreeHelper.GetChildrenCount(父级);
for(int i=0;i
您需要该控件做什么?也许有另一种方法可以在不引用ViewModel的情况下完成您要完成的任务。在使用MVVM时,没有一条规则可以消除代码中的所有代码。规则是“UI对象中只有UI代码”。如果您需要操作UI,但无法在XAML中操作,则“代码隐藏”是放置它的合适位置。@Rachel我需要FlowDocument将其转换为XPS文档,并将其附加到邮件消息中,然后在运行时将其一起发送,我想我不得不在FlowDocument@Rhyous同意,,我知道,通过引用ViewModel中的任何控件,我没有正确地使用MVVM,但是在这个特定任务中,我相信我必须这样做,只是为了澄清代码,我更喜欢使用干净的代码-behind@Musaab不能将FlowDocument的内容绑定到ViewModel中的属性吗?然后,要发送,您只需将绑定值作为邮件正文发送。这就成功了,谢谢,我同意我在这项特定任务中没有正确执行MVVM,如果能够以这种MVVM方式将包含数据绑定元素的FlowDocument转换为XPS文档,那将是非常好的,这里我对控件属性不感兴趣,实际上我对控件本身感兴趣。