将数据绑定到数据上下文之外的 class 实例

Bind Data to an instance of a class out of datacontext

下面的答案。

所以我正在使用 c# 和 WPF 为 Autodesk Revit 创建一个外部命令(加载项)。 我有这样的东西:

我的 视图 包含:

PWM = new PrintWindowModel(); // this is my ViewModel           
        InitializeComponent();
        DataContext = PWM;

我的 ViewModel 包含获取和设置数据的属性。所以我的数据绑定的这一部分工作正常。它还包含这个(Revit 的入口点):

public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
PrintMgr PrintManager = new PrintMgr(commandData);       
  //...
         return Result.Succeeded;
        }

PrintMgr 是我从 Revit SDK 获得的 class。这是一个非常有用的 class,但需要传递 commandData 才能工作。它使用 commandData 来设置当前文档和类似的东西。因为它需要 commandData,所以除了在此处实例化它之外别无选择。

现在,在我的 Xaml 中有一个组合框:

<ComboBox Name="AllPrinters"                     
                  DisplayMemberPath="Name"
                  ItemsSource="{Binding GetInstalledPrinters}"                      
                  SelectedItem="{Binding PrintManager.PrinterName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

现在,ItemsSource 工作正常。这里没问题。

问题在于 SelectedItem. 我绑定它的方式显然不起作用。 (仅供参考:PrintManager.PrinterName 确实有一个 get&set 属性。)

现在,如果我的 class 不需要 commandData,我可以去

private PrintMgr _printManager;
Public PrintMgr PrintManager 
{ 
get{return_printManager;}
set { _printManager=value;}
}

但是因为我的 class 确实需要 commandData,所以这无济于事。

编辑:

我补充了:

public string PrinterName 
{
get { return PrintManager.PrinterName; } 
set { PrintManager.PrinterName = value; } 
}

在我的 Xaml 中:

SelectedItem="{Binding PrinterName} 

然后我删除了datacontext=this;,在命令方法中添加了PrintWndow.Datacontext=this;

您仍然需要在 ViewModel 中添加 PrintManager 属性,但我建议您添加一个私有的 setter。

private PrintMgr _printManager;
public PrintMgr PrintManager 
{ 
    get{return_printManager;}
    private set { _printManager=value;}
}

在您的 ViewModel 命令处理程序中:

public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
{
     PrintManager = new PrintMgr(commandData);

     //...
     return Result.Succeeded;
}

这将在每次执行命令时更新您的 属性。

但我认为这不是您的最终答案,因为您仍然需要考虑如果多次执行该命令会怎样:是否要每次都重新生成 PrintManager?

并且如果在呈现视图之前未执行该命令,则绑定将不起作用,因为 PrintManager 属性 将为空。

在那种情况下,我为您提供了其他解决方案:)