簡體   English   中英

折疊時更改 RibbonGroup 可見部分的背景顏色

[英]Change background color of the visible part of a RibbonGroup when it is collapsed

我在 C# WPF 應用程序中使用 MS Ribbon 控件。 這個控件有幾個RibbonGroups 其中之一有RibbonButtons ,它可以在特定事件發生時改變它們的背景顏色。

只要這個RibbonGroup沒有折疊,彩色的RibbonButtons就可見,用戶可以注意到顏色的變化。 但是,如果應用程序 window 變小並且我的RibbonGroup折疊,則彩色RibbonButtons不在視圖中。

我試圖更改RibbonGroup的背景顏色,但此值設置為折疊的RibbonGroup的可見和不可見部分。

設置RibbonGroup.Header的背景顏色只會使帶有標題的TextBlock着色,而且此操作會使向下箭頭在RibbonGroup折疊時不可見。

這就是我的目標:

在此處輸入圖像描述

任何想法表示贊賞!

- - - - - 更新 - - - - - - -

我當前的實現如下所示。 我使用Bindings設置Buttons的背景 colors,使用Multibinding設置RibbonGroup的背景並響應IsCollapsedIsDropDownOpen屬性的變化。

這種方法的問題是 - 我必須在“正確”的時刻使用“正確”的顏色:當組沒有折疊時透明,當菜單下拉時為淺灰色等等。

...

xmlns:converters="clr-namespace:ControlFunctions.Converters"

...

<UserControl.Resources>
    <ResourceDictionary>
        <SolidColorBrush x:Key="RibbonBackground" Color="#f0f0f0" />
        <converters:ButtonBackgroundToGroupBackgroundConverter x:Key="ButtonBackgroundToGroupBackgroundConverter" />
    </ResourceDictionary>
</UserControl.Resources>
        
<Ribbon>
    <RibbonTab Header="Home">
        <RibbonGroup x:Name="_functionGroup" Header="Functions">
            <RibbonGroup.Background>
                    <MultiBinding Converter="{StaticResource ButtonBackgroundToGroupBackgroundConverter}" FallbackValue="{StaticResource RibbonBackground}" >
                            <Binding ElementName="_functionGroup" Path="IsCollapsed" />
                            <Binding ElementName="_functionGroup" Path="IsDropDownOpen" />
                            <Binding Path="Background_Button1" />
                            <Binding Path="Background_Button2" />
                            <Binding Path="Background_Button3" />
                    </MultiBinding>
            </RibbonGroup.Background>           
        
            <RibbonButton Label="Button 1" Background="{Binding Path=Background_Button1}" />
            <RibbonButton Label="Button 2" Background="{Binding Path=Background_Button2}" />
            <RibbonButton Label="Button 3" Background="{Binding Path=Background_Button3}" />
        </RibbonGroup>
    </RibbonTab>
</Ribbon>

轉換器.cs

public class ButtonBackgroundToGroupBackgroundConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        //no value set yet
        if (values[0] == DependencyProperty.UnsetValue || values[0] == null || values[1] == DependencyProperty.UnsetValue || values[1] == null) return Binding.DoNothing;
        
        if ((bool)values[0] == false) return null; //the group is not collapsed -> no background color, leave it transparent
        if ((bool)values[1]) return DependencyProperty.UnsetValue; //the group is collapsed AND menu is dropped down -> set Ribbon background color (=FallbackValue)

        for (int i = 2; i < values.Length; i++) if (values[i] != null) return values[i]; //one of the buttons is colored -> use its color for the group
        
        return null; //none of the buttons is colored -> no background color for the group, leave it transparent
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我的解決方案並不漂亮,但確實有效。

<!--A ribbon with SizeChanged event-->
<Ribbon DockPanel.Dock="Top" SizeChanged="Ribbon_SizeChanged">
    <RibbonTab Header="One">
        <!--A couple ribbon groups to fill up space-->
        <RibbonGroup Header="One">
            <RibbonButton Label="Button Number One"/>
        </RibbonGroup>
        <RibbonGroup Header="Two">
            <RibbonButton Label="Button Number Two"/>
        </RibbonGroup>
        
        <!--The ribbon group we want to change the color of, in this case named "Group"-->
        <RibbonGroup Header="Three" Name="Group">
            <RibbonButton Label="Button Number Three"/>
        </RibbonGroup>
    </RibbonTab>
</Ribbon>
private void Ribbon_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (Group.IsCollapsed && IWantToChangeRibbonGroupColor)
    {
        //Find the RibbonToggleButton inside the ribbon group
        var button = FindVisualChild<RibbonToggleButton>(Group);
        button.Background = Brushes.Green;
    }
}

//A common helper method I use for finding element children
public static ChildType FindVisualChild<ChildType>(DependencyObject obj) where ChildType : DependencyObject
{
    int num = VisualTreeHelper.GetChildrenCount(obj) - 1;
    for (int i = 0; i <= num; i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(obj, i);
        if (child != null && child is ChildType)
        {
            return (ChildType)child;
        }

        child = FindVisualChild<ChildType>(child);
        if (child != null)
        {
            return (ChildType)child;
        }
    }

    return null;
}

這可以被包裝成一個簡潔的小附加行為,但我現在不想經歷那種努力。

據我所知,沒有一個屬性可以讓您更改您想要的內容,但是沒有什么可以阻止您挖掘可視化樹並手動更改背景顏色。 使用 Visual Studio 中的可視化樹調試工具,您可以看到哪些元素組成了折疊的RibbonGroup

功能區視覺樹

在這種情況下,看起來最好的改變顏色的內部元素是RibbonToggleButton

該代碼的目的是找出RibbonGroup折疊,獲取對其中RibbonToggleButton的引用,然后設置Background

不幸的是,當RibbonGroup切換到或退出其折疊的 state 時,我找不到任何事件。但至少有一個屬性: RibbonGroup.IsCollapsed 我合理地假設IsCollapsed只會在整個 Ribbon 的大小發生變化時發生變化,因此我選擇檢查IsCollapsed inside Ribbon.SizeChanged (注意:我首先嘗試使用RibbonGroup.SizeChanged ,但這並不能正常工作RibbonGroup有時會恢復到其原始顏色。)

在我提供的示例代碼中,我通過為RibbonGroup命名獲得了對我想使用的RibbonGroup的引用,但如前所述,您可以通過其他方式實現它,例如通過設計附加行為 獲得RibbonGroup ,我會遍歷所有子元素,尋找RibbonToggleButton 當我找到它時,我設置了背景。 只要RibbonGroupControlTemplate保持不變,這就應該繼續工作。

根據您對IWantToChangeRibbonGroupColor的實施,您可能還希望在IWantToChangeRibbonGroupColor的值發生變化時運行顏色更改方法。 這樣即使色帶的尺寸不變,顏色也會發生變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM