将数据绑定到数据上下文之外的 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 属性 将为空。
在那种情况下,我为您提供了其他解决方案:)
下面的答案。
所以我正在使用 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 属性 将为空。
在那种情况下,我为您提供了其他解决方案:)