我们小组正在围绕我们的电子邮件活动开发自定义活动设计器。它是一个非常直接的设计师,允许用户输入设置/信誉,但不是使用所有可设置的选项使活动设计器混乱,我们考虑在对话窗口中放置一些设置。 (单击服务器地址框旁边的按钮时会打开。)
我们的一些电子邮件活动属性是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" />
如果有人对如何在对话中完成此操作有任何想法,请提供建议。
答案 0 :(得分:0)
嗯,这真的比WF4更像是一个WPF \ MVVM问题。
在开发自定义活动时,您只需记住一件事: 对设计师\对象所做的任何更改都应反映在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的工作原理,它可能会有点棘手。但这是一个非常好的方法。
答案 1 :(得分:0)
我通过在对话框的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" />
因为我现在从活动设计器直接绑定到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()
}