0

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

如何设置绑定应绑定到的属性?如果我创建一个带有 的控件x:Name="SomeProperty",我该如何选择是否SomeProperty应该将 的值绑定到我的控件的Value属性、我的控件的OnClick事件或不同的东西,如ContentTag属性?

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

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

然而,Content 属性不是用 URL 的值填充的,Read more而是用 URL 的值填充的。在此示例中,我如何:

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

任何人都可以帮助我吗?

4

1 回答 1

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),您可以保持原样,它应该保持“阅读更多...”

所以现在你有一个HyperlinkButton控件,它应该按照约定绑定到,并在触发事件NavigateUri时调用共享它的名称的方法。Click

编辑:

我可能会澄清一下,我认为您不能同时绑定到同一VM 上的方法和属性,因为您不能拥有共享相同名称的方法和属性,但我确信 CM 会冒泡如果您在 VM 上没有适当的方法,则将操作消息向上传递到 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方法。

于 2012-11-26T21:28:32.780 回答