选择时按钮模板样式

时间:2012-04-11 15:00:59

标签: c# wpf mvvm

我设置了mvvm设计模式来执行命令和工作区,以便按下按钮并显示正确的工作区。按钮具有模板绑定,可根据命令为模板提取正确的图像。我在命令中为SelectedTemplateResource添加了另一个字段,用于从按钮数组中选择按钮时。 DataTemplate被拉入主窗口以显示按钮。

<DataTemplate x:Key="CommandsTemplate">
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}" Template="{Utilities:BindableResource {Binding Path=TemplateResource}}">
                    <Button.Style>
                        <Style TargetType="Button">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Path=Command}">
                                    <Setter Property="Template">
                                        <Setter.Value>

                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</DataTemplate>

我想要做的是将setter的值设置为SelectedTemplateResource,就像在名为TemplateResource的按钮的模板中一样。这些都是通过mainwindowviewmodel处理来设置每个按钮的相应模板,它运行良好,但我不知道如何完成选定的状态。

另外,我不完全确定我是否应该将datatrigger绑定到命令路径。

有人可以帮我弄清楚如何使用上面提到的设计设置按钮的选定状态吗?

干杯。

修改 我得到了togglebutton触发器的使用,但绑定不起作用。继承了一些更多信息,因为我在app.xaml.cs

中一直得到密钥是空错误

ToggleButton是名为MainWindowResources.xaml( ResourceDictionary )的文件中的datatemplate。 MainWindow.xaml文件会提取此数据模板。 我有一个bindableresource类来帮助处理资源文件的静态资源。

public class BindableResource : StaticResourceExtension
{
    #region Fields
    private static readonly DependencyProperty dummyProperty;
    #endregion


    #region Properties
    /// <summary>
    /// Gets and sets my binding.
    /// </summary>
    public Binding MyBinding { get; set; }
    #endregion


    #region Constructor
    /// <summary>
    /// Static contruction of the dummy dependency property.
    /// </summary>
    static BindableResource()
    {
        dummyProperty = DependencyProperty.RegisterAttached("Dummy", typeof(string), typeof(DependencyObject), new UIPropertyMetadata(null));
    }

    /// <summary>
    /// Constructor.
    /// </summary>
    public BindableResource()
    {
    }

    /// <summary>
    /// Constructor with binding to set.
    /// </summary>
    /// <param name="binding"></param>
    public BindableResource(Binding binding)
    {
        MyBinding = binding;
    }
    #endregion


    #region External Members
    /// <summary>
    /// Get the resource key to bind to the resource.
    /// </summary>
    /// <param name="serviceProvider"></param>
    /// <returns></returns>
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
        var targetObject = (FrameworkElement)target.TargetObject;

        MyBinding.Source = targetObject.DataContext;
        var DummyDO = new DependencyObject();
        BindingOperations.SetBinding(DummyDO, dummyProperty, MyBinding);

        ResourceKey = DummyDO.GetValue(dummyProperty);

        return base.ProvideValue(serviceProvider);
    }
    #endregion
}

但是这对触发器设置器值不起作用。

<DataTemplate>
                <ToggleButton Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}" Template="{Utilities:BindableResource {Binding Path=TemplateResource}}">
                    <ToggleButton.Style>
                        <Style TargetType="ToggleButton">
                            <Style.Triggers>
                                <Trigger Property="IsChecked" Value="True">
                                    <Setter Property="Template" Value="{Utilities:BindableResource {Binding Path=SelectedTemplateResource}}" />
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </ToggleButton.Style>
                </ToggleButton>
            </DataTemplate>

有什么想法或想法吗?

2 个答案:

答案 0 :(得分:2)

我不确定我是否完全理解你想要的东西。如果选择是,您想要更改按钮的模板吗?

首先,标准按钮没有被“选中”的概念。你需要一个ToggleButton。这样,您可以在其IsChecked属性上触发设置模板。

<DataTemplate x:Key="CommandsTemplate">
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ToggleButton Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}" Template="{Utilities:BindableResource {Binding Path=TemplateResource}}">
                    <ToggleButton.Style>
                        <Style TargetType="ToggleButton">
                            <Style.Triggers>
                                <Trigger Property="IsChecked" Value="True">
                                    <Setter Property="Template" Value="{Utilities:BindableResource {Binding DataContext.SelectedTemplateResource}}">
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </ToggleButton.Style>
                </ToggleButton>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</DataTemplate>

答案 1 :(得分:0)

在发现这真的不可能在纯xaml中做了我带出了c#并创建了一个自定义控件...这是非常基本的,可以改进,我会改变一点但最终是自定义控件解决了这个问题,以便您可以从资源字典中点击click事件并动态更改模板。

public class TabButton : Button
{
    public static readonly DependencyProperty SelectedTemplateProperty = 
        DependencyProperty.Register("SelectedTemplate", typeof(ControlTemplate), typeof(TabButton));

    public ControlTemplate SelectedTemplate
    {
        get { return base.GetValue(SelectedTemplateProperty) as ControlTemplate; }
        set { base.SetValue(SelectedTemplateProperty, value); }
    }

    public TabButton()
    {
        this.Click += new RoutedEventHandler(TabButton_Click);
    }

    ~TabButton()
    {

    }

    public void TabButton_Click(object sender, RoutedEventArgs e)
    {
        ControlTemplate template = (ControlTemplate)this.FindResource("Environmental Template Selected");
        (sender as TabButton).Template = template;
    }
}

干杯。