我正在使用来自Caliburn.Micro的基于约定的绑定,但我有一个小问题:
如何设置绑定应绑定的属性?如果我使用x:Name="SomeProperty"
创建了一个控件,如何选择SomeProperty
的值是否应绑定到我的控件的Value
属性,即我控制的OnClick
事件或者不同的东西,比如Content
或Tag
属性?
示例:我想要绑定到特定URL的HyperlinkButton
,我想将OnClick
绑定到ViewModel中的事件处理程序。
<HyperlinkButton x:Name="BookDetailsViewModel_InfoLink" Content="Read more" />
然而,Content属性未填充Read more
,而是带有URL的值。在这个例子中,我该如何:
有人可以帮我吗?
答案 0 :(得分:1)
您可以在CM中为每种元素类型自定义ConventionManager。默认的开箱即用实现适用于任何没有显式定制的元素
要添加新约定,您只需调用ConventionManager.AddElementConvention
即可该方法如下(来自CM源)
/// <summary>
/// Adds an element convention.
/// </summary>
/// <typeparam name="T">The type of element.</typeparam>
/// <param name="bindableProperty">The default property for binding conventions.</param>
/// <param name="parameterProperty">The default property for action parameters.</param>
/// <param name="eventName">The default event to trigger actions.</param>
public static ElementConvention AddElementConvention<T>(DependencyProperty bindableProperty, string parameterProperty, string eventName)
{
return AddElementConvention(new ElementConvention
{
ElementType = typeof(T),
GetBindableProperty = element => bindableProperty,
ParameterProperty = parameterProperty,
CreateTrigger = () => new EventTrigger { EventName = eventName }
});
}
如您所见,它需要一些参数 - 您需要传递绑定,操作和触发器的默认属性,例如。
ConventionManager.AddElementConvention<HyperlinkButton>(HyperlinkButton.NavigateUri, "NavigateUri", "Click");
(假设点击事件被称为Click)
由于您不再绑定Content
属性(因为约定现在绑定NavigateUri),您可以保持原样并保持“Read more ...”
所以现在你有一个HyperlinkButton
控件,它应该按约定绑定到NavigateUri
,并在触发Click
事件时调用共享它名字的方法。
编辑:
我可能会澄清一下,我认为你不能绑定两者同一个VM上的方法和属性,因为你不能拥有一个方法和一个属性共享相同的名称,但我确信如果您在VM上没有适当的方法,CM会将操作消息冒泡到VM层次结构中...但是没试过它。要绑定操作,请参阅下面的其他编辑
不要忘记,您可以随时使用显式语法!
<HyperlinkButton Content="Read more..." NavigationURI="{Binding SomeUri}" cal:Message.Attach="[Event Click] = [Action HyperlinkClicked($this.NavigateUri)" />
但是去常规路线可能会更好:)
编辑:
可能会添加如何让约定从超链接中获取属性值 -
<HyperlinkButton x:Name="SomeLink" Content="Read more..." cal:Message.Attach="HyperlinkClicked(SomeLink)" />
CM知道,因为您将NavigateUri
设置为默认操作参数,所以它应该抓住它并将其传递给您在操作绑定中指定的方法。我想知道$this
是否也会起作用(你可能需要$this.NavigateUri
)。您可以跨控件执行此操作,例如
<TextBox x:Name="SomeTextBox" />
<HyperlinkButton x:Name="SomeLink" Content="Read more..." cal:Message.Attach="HyperlinkClicked(SomeTextBox)" />
默认情况下,上述内容会将文本框的Text
属性传递给HyperlinkClicked
方法。