[英]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
的背景並響應IsCollapsed
和IsDropDownOpen
屬性的變化。
這種方法的問題是 - 我必須在“正確”的時刻使用“正確”的顏色:當組沒有折疊時透明,當菜單下拉時為淺灰色等等。
...
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
。 當我找到它時,我設置了背景。 只要RibbonGroup
的ControlTemplate
保持不變,這就應該繼續工作。
根據您對IWantToChangeRibbonGroupColor
的實施,您可能還希望在IWantToChangeRibbonGroupColor
的值發生變化時運行顏色更改方法。 這樣即使色帶的尺寸不變,顏色也會發生變化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.