![](/img/trans.png)
[英]How to change the Foreground color of a button in a DataGrid depending on values from another column? WPF c#
[英]How to Change Button Foreground Color Conditionally in WPF?
我在ItemsControl
(分頁類型控件)中有一個按鈕,我的視圖模型中有一個名為current_page
的屬性。
我想將current_page
值與 (1 / 2 / 3) 的Button
Content
進行比較,並想更改按鈕的前景色。
請看一下代碼。
我的視圖模型
public PaginationModel pagination
{
get { return _pagination; }
set { _pagination = value; OnPropertyChanged("pagination"); }
}
我的分頁模型
public class PaginationModel: INotifyPropertyChanged {
private int _total_items;
public int total_items {
get {
return _total_items;
}
set {
_total_items = value;
OnPropertyChanged("total_items");
}
}
private int _items_per_page;
public int items_per_page {
get {
return _items_per_page;
}
set {
_items_per_page = value;
OnPropertyChanged("items_per_page");
}
}
private int _current_page;
public int current_page {
get {
return _current_page;
}
set {
if (value <= total_pages + 1 && value > 0) {
_current_page = value;
OnPropertyChanged("current_page");
}
}
}
private int _total_pages;
public int total_pages {
get {
return _total_pages;
}
set {
_total_pages = value;
OnPropertyChanged("total_pages");
}
}
private ObservableCollection < string > _PageList;
public ObservableCollection < string > PageList {
get {
_PageList = new ObservableCollection < string > ();
for (int i = 0; i < total_pages; i++) {
_PageList.Add((i + 1).ToString());
}
return _PageList;
}
set {
_PageList = value;
OnPropertyChanged("PageList");
}
}
}
我的布局
<ItemsControl ItemsSource="{Binding pagination.PageList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0">
<Button Content="{Binding}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Command="{Binding DataContext.ChangePage, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
Width="20"
Margin="10,0"></Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
按鈕樣式模板
<Style TargetType="{x:Type Button}" >
<Setter Property="Foreground" Value="{StaticResource WordOrangeBrush}" />
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
<Setter Property="FontFamily" Value="{StaticResource HelveticaNeue}"></Setter>
<Setter Property="FontSize" Value="14"></Setter>
<Setter Property="Foreground" Value="#ff9f00"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="Foreground" Value="#ff9f00" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="Foreground" Value="White" />
</Trigger>
<!--I want to bind current page value in place of 1-->
<DataTrigger Binding="{Binding}" Value="1">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
您不能將DataTrigger
的Value
綁定到屬性,因為它不是依賴屬性。 您可以通過創建一個用於檢查頁面是否相等的自定義多值轉換器來解決此問題。
public class PageEqualityToBooleanConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return (int)values[0] == System.Convert.ToInt32(values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
傳遞給轉換器的第一個值是作為int
的當前頁面,第二個值是作為string
的Button
上的頁面。 您的current_page
是int
類型有點奇怪,但PageList
是string
類型的集合,這就是我們需要轉換第二個值的原因。
在樣式之前在資源中創建轉換器的實例,以便您可以引用它。
<local:PageEqualityToBooleanConverter x:Key="PageEqualityToBooleanConverter"/>
最后,用下面的替換你的DataTrigger
。 我們正在使用MultiBinding
來綁定多個值。 如果頁面值匹配,轉換器會將兩個值都轉換為True
,否則轉換為False
。
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource PageEqualityToBooleanConverter}">
<Binding Path="DataContext.pagination.current_page" RelativeSource="{RelativeSource AncestorType={x:Type ItemsControl}}"/>
<Binding/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
第一個綁定將找到父項ItemsControl
以訪問包含current_page
的視圖模型。 第二個綁定將綁定到關聯按鈕的數據上下文,即頁面字符串。 如果您將PageList
項目類型更改為int
這仍然有效。
我想指出一些對您的代碼的觀察,可能會幫助您改進它。
int
或創建單獨的頁面項視圖模型。Button
定義隱式樣式,該樣式應用於范圍內的所有Button
控件。 如果您僅在分頁控件中使用它,這可能沒問題,但如果您打算在其他地方使用它, DataTrigger
應將DataTrigger
包含在其中,因為它僅特定於此數據上下文。 在此基礎上創建單獨的樣式。 考慮@BionicCode 對此的評論。ListBox
可能更適合分頁器,因為它具有SelectedItem
的概念(以及可以綁定在DataTrigger
項目容器上的IsSelected
屬性),這就是您的想法試圖在這里手動完成。 DataTrigger
的Value
屬性不能是數據綁定的。
你應該做的是創建一個代表一個類型Page
,一個加Number
和IsCurrentPage
屬性並更改類型PageList
是一個ObservableCollection<Page>
代替ObservableCollection<string>
。
然后,您可以簡單地查找相應的Page
中PageList
並設置其IsCurrentPage
每當從視圖模型屬性current_page
屬性設置。
您還應該確保PageList
屬性的 getter 不會在每次調用時創建新集合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.