我在ControlTemplate中有一个按钮。我如何获得它的参考?

时间:2008-10-08 20:58:12

标签: wpf controltemplate

我只想在ControlTemplate中为我正在使用的WPF编辑器启用或禁用该按钮。

4 个答案:

答案 0 :(得分:4)

我建议您通过RoutedUICommands轻松控制按钮 - 包括轻松启用和禁用它们。命令不需要任何类型的Button引用,所以这也解决了你的问题。

见这里:

<Window.CommandBindings>
    <CommandBinding 
        Command="{x:Static local:MyCommands.MyCommand}"
        Executed="CommandBinding_Executed"
        CanExecute="CommandBinding_CanExecute" />
</Window.CommandBindings>

<Window.Resources>
    <ControlTemplate x:Key="MyTemplate" TargetType="Label">
        <Button Command="{x:Static local:MyCommands.MyCommand}">
            <TextBlock>
                Click Me
                <TextBlock Text="{TemplateBinding Content}" />
            </TextBlock>
        </Button>
    </ControlTemplate>
</Window.Resources>

<StackPanel>
    <Label Template="{StaticResource MyTemplate}">1</Label>
    <Label Template="{StaticResource MyTemplate}">2</Label>
    <Label Template="{StaticResource MyTemplate}">3</Label>
    <Label Template="{StaticResource MyTemplate}">4</Label>
    <Label Template="{StaticResource MyTemplate}">5</Label>
</StackPanel>

使用此:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void CommandBinding_CanExecute(object sender, System.Windows.Input.CanExecuteRoutedEventArgs e)
    {
        // your logic here
        int _Integer = -1;
        int.TryParse(e.Parameter.ToString(), out _Integer);
        e.CanExecute = _Integer % 2 == 0;
    }

    private void CommandBinding_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
    {
        // do something when clicked
    }
}

public static class MyCommands
{
    public static RoutedUICommand MyCommand = new RoutedUICommand();
}

看起来像:

screenshot

答案 1 :(得分:3)

你真的不应该明确地这样做,而是在ControlTemplate本身的触发器中设置它。这些触发器将对其他一些更改做出反应,并会设置Enabled的{​​{1}}属性。

答案 2 :(得分:2)

我同意Joel的观点,首选的方法是通过触发器或通过将Enabled值绑定到另一个依赖项属性(可能在父元素上)来触发使用xaml标记设置按钮的Enabled属性。 ValueConverter的帮助。

但是,如果必须在C#中显式执行,则可以在按钮的模板属性上使用FindName()方法。有一个MSDN'如何'linked here

答案 3 :(得分:0)

我在controlTemplates&amp;中遇到了按钮问题。的DataTemplates。我发现触发器通常太麻烦,无法提供我的客户想要的东西,我最终得到了太多的转换器。我首先尝试的方法是内联定义这些更难的模板,以便它们可以绑定到我的屏幕ViewModel上的命令(&amp; codebehind events)。

如果你正在模仿你自己的控制,我应该提到最简单的方法是简单地命名按钮然后使用这样的东西:

hourHand   = this.Template.FindName( "PART_HourHand",   this ) as Rectangle;

最近,我改变了机智(回到不定的文件......重新使用!)但是开始添加一个ViewModel(各种各样),我后缀...TemplateCommandStore到我的所有模板都有点复杂。我甚至在模板化我的自定义控件时使用它(为了保持一致性)

public class BookingDetailsTemplateCommandStore
{
    public OpenWindowCommand_Command OpenWindowCommand_Command { get; set; }

    public BookingDetailsTemplateCommandStore()
    {
        OpenWindowCommand_Command = new OpenWindowCommand_Command( this );
    }       
}

然后我可以在模板中愉快地使用此命令。您还可以通过将(dependancy?)属性绑定到命令存储区来将控制引用传递到命令存储区以捕获事件&amp;切除对模板的更精确控制。

<DataTemplate DataType="{x:Type LeisureServices:BookingSummary}">
    <Border Height="50" otherStyling="xyz">
        <Border.Resources>
            <local:BookingDetailsTemplateCommandStore x:Key="CommandStore" />
        </Border.Resources>
        <DockPanel>
            <Button otherStyling="xyz"
                    Command="{Binding Source={StaticResource CommandStore},
                                      Path=OpenWindowCommand_Command}" />

MVVM:我发现,只要图形逻辑就是这样,并且完全不同于业务逻辑,这种方法就不会干扰MVVM。从本质上讲,我为模板添加了一致的C#代码功能,任何在winforms上花费太多时间的人都可能会错过我。