sup*_*jos 4 c# wpf xaml caliburn.micro
我有一个由Caliburn.Micro支持的WPF应用程序,它是视图模型优先方法。有一个命令栏类型的控件,其CommandBarView.xaml和绑定的CommandBarViewModel。命令行VM包含许多嵌套的VM,每个按钮控件一个VM,它们都显示一个公共界面并具有相同的行为。命令行VM公开它们,以便可以从视图中对其进行绑定:
public interface IWarningButtonViewModel
{
bool IsVisible { get; }
bool CanShowWarning { get; }
void ShowWarning();
}
public class CommandBarViewModel : PropertyChangedBase
{
public IWarningButtonViewModel UserNotFoundWarning { get; private set; }
public IWarningButtonViewModel NetworkProblemWarning { get; private set; }
// ... initialization omitted for simplicity
}
Run Code Online (Sandbox Code Playgroud)
这是一些CommandBarView的暂定XAML:
<Button x:Name="UserNotFoundWarning_ShowWarning"
IsEnabled="{Binding UserNotFoundWarning.CanShowWarning}">
...
<DataTrigger Binding="{Binding UserNotFoundWarning.IsVisible}" Value="True">
...
</Button>
Run Code Online (Sandbox Code Playgroud)
这样,我就可以成功绑定两个属性(CanShowWarning,IsVisible),但无法将按钮命令/操作绑定到ShowWarning方法。
我尝试使用深层属性绑定,但对于属性,它又可以工作,但对于动作而言,它却不能工作。
我也试过用的混合cal:Model.Bind和cal:Message.Attach:
<Button cal:Model.Bind="{Binding UserNotFoundWarning}"
cal:Message.Attach="[Event Click] = [Action ShowWarning]"
IsEnabled="{Binding CanShowWarning}">
...
<DataTrigger Binding="{Binding IsVisible}" Value="True">
...
</Button>
Run Code Online (Sandbox Code Playgroud)
这似乎在运行时有效,但是cal:Model.Bind使VS设计器完全不可用,UI控件未显示。
我已经搜索了很多东西,但是找不到实际的解决方案让我也可以与设计师一起工作。对于我而言,我只能找到针对属性而非操作进行深度绑定的示例,这对我来说似乎很奇怪。
任何想法如何解决这个问题?
这是我的解决方法:
private static void EnableNestedViewModelActionBinding()
{
var baseGetTargetMethod = ActionMessage.GetTargetMethod;
ActionMessage.GetTargetMethod = (message, target) =>
{
var methodName = GetRealMethodName(message.MethodName, ref target);
if (methodName == null)
return null;
var fakeMessage = new ActionMessage { MethodName = methodName };
foreach (var p in message.Parameters)
fakeMessage.Parameters.Add(p);
return baseGetTargetMethod(fakeMessage, target);
};
var baseSetMethodBinding = ActionMessage.SetMethodBinding;
ActionMessage.SetMethodBinding = context =>
{
baseSetMethodBinding(context);
var target = context.Target;
if (target != null)
{
GetRealMethodName(context.Message.MethodName, ref target);
context.Target = target;
}
};
}
private static string GetRealMethodName(string methodName, ref object target)
{
var parts = methodName.Split('.');
var model = target;
foreach (var propName in parts.Take(parts.Length - 1))
{
if (model == null)
return null;
var prop = model.GetType().GetPropertyCaseInsensitive(propName);
if (prop == null || !prop.CanRead)
return null;
model = prop.GetValue(model);
}
target = model;
return parts.Last();
}
Run Code Online (Sandbox Code Playgroud)
EnableNestedViewModelActionBinding()从引导程序中调用一次,它将使您能够使用通常的点分符号将动作绑定到嵌套模型的方法。例如
cal:Message.Attach="[Event Click] = [Action UserNotFoundWarning.ShowWarning]"
Run Code Online (Sandbox Code Playgroud)
编辑:请注意,如果您在运行时更改嵌套的ViewModel实例,则此方法将无效。例如,如果您UserNotFoundWarning在绑定发生后将您分配给新的东西-Caliburn仍会在先前实例上调用操作。
| 归档时间: |
|
| 查看次数: |
1374 次 |
| 最近记录: |