如何绑定控件属性?

时间:2012-11-23 15:30:26

标签: data-binding mvvm windows-runtime caliburn.micro caliburn

我正在使用来自Caliburn.Micro的基于约定的绑定,但我有一个小问题:

如何设置绑定应绑定的属性?如果我使用x:Name="SomeProperty"创建了一个控件,如何选择SomeProperty的值是否应绑定到我的控件的Value属性,即我控制的OnClick事件或者不同的东西,比如ContentTag属性?

示例:我想要绑定到特定URL的HyperlinkButton,我想将OnClick绑定到ViewModel中的事件处理程序。

<HyperlinkButton x:Name="BookDetailsViewModel_InfoLink" Content="Read more" />

然而,Content属性未填充Read more,而是带有URL的值。在这个例子中,我该如何:

  • 将导航URI设置为我的ViewModel属性中的URL值
  • 将内容设置为“阅读更多”
  • 在我的ViewModel中指定将处理点击的事件处理程序

有人可以帮我吗?

1 个答案:

答案 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方法。