在对话框中使用时如何配置 ExpressionTextBox 绑定/OwnerActivity?
How to configure ExpressionTextBox bindings / OwnerActivity when used in a dialog?
我们的小组正在围绕我们的电子邮件 activity 开发自定义 Activity 设计器。这是一个非常直接的设计器,允许用户输入设置/凭据,但我们考虑将一些设置放在对话框中 window,而不是用所有可设置的选项使 activity 设计器变得混乱。 (当您单击服务器地址框旁边的按钮时打开)。
我们的一些电子邮件 activity 属性是 InArguments 因此我们尝试使用 ExpressionTextBox 来显示这些值但运气不佳。主要问题是我们不确定如何在 ExpressionTextBox 上正确设置绑定和 OwnerActivity。在 Activity Designer 的 xaml 中,这只需使用 InArgument 的转换器设置 Expression=ModelItem.Property 并设置 OwnerActivity=ModelItem 即可完成,如下所示:
<view:ExpressionTextBox HintText="Enter a VB Expression" Expression="{Binding ModelItem.ServerAddress, ConverterParameter=In, Converter={StaticResource ArgumentToExpressionConverter}, Mode=TwoWay}" ExpressionType="{x:Type system:String}" OwnerActivity="{Binding ModelItem}" Margin="2" MaxLines="1" />
如果有人对我们如何在对话中完成此操作有任何想法,请提出建议。
嗯,这比 WF4 更 WPF\MVVM 问题,真的。
开发自定义活动设计器时,您只需牢记一件事:在 designer\dialog 上所做的任何更改都应反映在 ModelItem
上。 通过 XAML 绑定表达式或通过 ModelItem.Properties
属性.
上的代码
现在,您何时以及如何做,有几个答案,但这实际上是一个实施细节,取决于您想要如何做。
假设您在单击按钮旁边的服务器地址框 时显示对话框。并假设您可以通过名称访问对话框文本框。届时,您可以访问 ModelItem
,因此只需根据需要设置其属性即可:
private void ButtonNextToServerAddressBox_OnClick(object sender, RoutedEventArgs e)
{
var dialog = new ServerAddressEditor();
var result = dialog.ShowDialog();
if (result ?? false)
{
ModelItem.Properties["Server"].SetValue(new InArgument<string>(dialog.ServerTextBox.Text));
ModelItem.Properties["Port"].SetValue(new InArgument<string>(dialog.PortTextBox.Text));
// ... set all other properties
}
}
现在,如果您使用任何其他模式,或者您想要纯 MVVM,由于 ModelItem 的工作方式,它可能会更棘手一些。但这是一个完全好的方法。
我通过在对话框的 ViewModel 中创建一个 属性 来保存 Activity Designer 的 ModelItem 来解决这个问题。
public ModelItem OwnerActivity {
get { return _OwnerActivity; }
set { _OwnerActivity = value; }
}
vm.OwnerActivity = this.DataContext.ModelItem;
然后我将对话框中表达式文本框的 Xaml 设置为绑定到此:
<view:ExpressionTextBox HintText="Enter a VB Expression" Expression="
{Binding Path=OwnerActivity.ServerAddress, ConverterParameter=In, Converter=
{StaticResource ArgumentToExpressionConverter}, Mode=TwoWay}" ExpressionType="
{x:Type system:String}" OwnerActivity="{Binding OwnerActivity}" Margin="2"
MaxLines="1" />
因为我现在直接绑定到来自 Activity 设计器的 ModelItem,所以从对话框 属性 对 ModelItem 所做的任何更改总是提交,即使您从对话。为了连接 Ok/Cancel 按钮以便它们相应地工作,我在对话框中执行了以下操作:
// declare a ModelEditingScope to make changes transactional
private ModelEditingScope _editScope;
// add this to the constructor of the dialog to begin transactional edits on the ModelItem
_editScope = editorViewModel.OwnerActivity.BeginEdit();
// ok & cancel button click event to commit or revert the changes.
private void OK_Click(object sender, RoutedEventArgs e)
{
_editScope.Complete();
this.DialogResult = DialogResult.OK;
this.Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
_editScope.Revert();
this.DialogResult = DialogResult.Cancel;
this.Close()
}
我们的小组正在围绕我们的电子邮件 activity 开发自定义 Activity 设计器。这是一个非常直接的设计器,允许用户输入设置/凭据,但我们考虑将一些设置放在对话框中 window,而不是用所有可设置的选项使 activity 设计器变得混乱。 (当您单击服务器地址框旁边的按钮时打开)。
<view:ExpressionTextBox HintText="Enter a VB Expression" Expression="{Binding ModelItem.ServerAddress, ConverterParameter=In, Converter={StaticResource ArgumentToExpressionConverter}, Mode=TwoWay}" ExpressionType="{x:Type system:String}" OwnerActivity="{Binding ModelItem}" Margin="2" MaxLines="1" />
如果有人对我们如何在对话中完成此操作有任何想法,请提出建议。
嗯,这比 WF4 更 WPF\MVVM 问题,真的。
开发自定义活动设计器时,您只需牢记一件事:在 designer\dialog 上所做的任何更改都应反映在 ModelItem
上。 通过 XAML 绑定表达式或通过 ModelItem.Properties
属性.
现在,您何时以及如何做,有几个答案,但这实际上是一个实施细节,取决于您想要如何做。
假设您在单击按钮旁边的服务器地址框 时显示对话框。并假设您可以通过名称访问对话框文本框。届时,您可以访问 ModelItem
,因此只需根据需要设置其属性即可:
private void ButtonNextToServerAddressBox_OnClick(object sender, RoutedEventArgs e)
{
var dialog = new ServerAddressEditor();
var result = dialog.ShowDialog();
if (result ?? false)
{
ModelItem.Properties["Server"].SetValue(new InArgument<string>(dialog.ServerTextBox.Text));
ModelItem.Properties["Port"].SetValue(new InArgument<string>(dialog.PortTextBox.Text));
// ... set all other properties
}
}
现在,如果您使用任何其他模式,或者您想要纯 MVVM,由于 ModelItem 的工作方式,它可能会更棘手一些。但这是一个完全好的方法。
我通过在对话框的 ViewModel 中创建一个 属性 来保存 Activity Designer 的 ModelItem 来解决这个问题。
public ModelItem OwnerActivity {
get { return _OwnerActivity; }
set { _OwnerActivity = value; }
}
vm.OwnerActivity = this.DataContext.ModelItem;
然后我将对话框中表达式文本框的 Xaml 设置为绑定到此:
<view:ExpressionTextBox HintText="Enter a VB Expression" Expression="
{Binding Path=OwnerActivity.ServerAddress, ConverterParameter=In, Converter=
{StaticResource ArgumentToExpressionConverter}, Mode=TwoWay}" ExpressionType="
{x:Type system:String}" OwnerActivity="{Binding OwnerActivity}" Margin="2"
MaxLines="1" />
因为我现在直接绑定到来自 Activity 设计器的 ModelItem,所以从对话框 属性 对 ModelItem 所做的任何更改总是提交,即使您从对话。为了连接 Ok/Cancel 按钮以便它们相应地工作,我在对话框中执行了以下操作:
// declare a ModelEditingScope to make changes transactional
private ModelEditingScope _editScope;
// add this to the constructor of the dialog to begin transactional edits on the ModelItem
_editScope = editorViewModel.OwnerActivity.BeginEdit();
// ok & cancel button click event to commit or revert the changes.
private void OK_Click(object sender, RoutedEventArgs e)
{
_editScope.Complete();
this.DialogResult = DialogResult.OK;
this.Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
_editScope.Revert();
this.DialogResult = DialogResult.Cancel;
this.Close()
}