【问题标题】:Button Template style when selected选择时的按钮模板样式
【发布时间】:2012-04-11 15:00:58
【问题描述】:

我设置了一个 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 处理的,为每个按钮设置适当的模板,效果很好,但我不确定如何完成选定的状态。

另外,我不完全确定是否应该将数据触发器绑定设置为命令路径。

谁能帮我弄清楚如何使用上述设计设置按钮的选定状态?

干杯。

编辑 我使用了切换按钮触发器,但是绑定不起作用。这里有一些更多信息,因为出于某种原因,我在 app.xaml.cs 中不断收到 key is null 错误

ToggleButton 是名为 MainWindowResources.xaml (ResourceDictionary) 的文件中的数据模板。 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>

有什么想法或想法吗?

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

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

    首先,标准按钮没有“被选中”的概念。你想要一个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>
    

    【讨论】:

    • 这正是我要找的,切换按钮确实更有意义,但是单击按钮时模板不会切换。
    • 您能否检查您的输出是否存在绑定错误。我只是猜测了 setter 中的绑定路径。
    • 一直说键为空...输出控制台中没有任何内容...该方法看起来正确,可能只是一个愚蠢的绑定约束。
    • 现在想起来了,key就值而言是null,不知道是不是和我处理服务的bindableresource类有关系。我还应该注意,此数据模板位于资源文件中。
    • 我已经用绑定问题编辑了我的问题...仍然没有运气。
    【解决方案2】:

    在发现这在纯 xaml 中确实不可能做到之后,我拿出了 c# 并创建了一个自定义控件...这是非常基本的,可以改进,我将对其进行一些更改,但最终自定义控件解决了这个问题,因此您可以从资源字典中点击点击事件并动态更改模板。

    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;
        }
    }
    

    干杯。

    【讨论】:

      猜你喜欢
      • 2018-11-01
      • 1970-01-01
      • 2017-04-04
      • 2013-11-27
      • 1970-01-01
      • 2014-11-05
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      相关资源
      最近更新 更多