0

我设置了一个 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>

有什么想法或想法吗?

4

2 回答 2

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>
于 2012-04-11T15:20:50.123 回答
0

在发现在纯 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;
    }
}

干杯。

于 2012-04-12T13:20:30.657 回答