Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WPF中有条件地更改按钮前景色?_C#_Wpf_Xaml_Data Binding - Fatal编程技术网

C# 如何在WPF中有条件地更改按钮前景色?

C# 如何在WPF中有条件地更改按钮前景色?,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,我在ItemsControl分页种类控件中有一个按钮我在视图模型中有一个名为current_page的属性 我想将当前页面值与1/2/3的按钮内容进行比较,并想更改按钮的前景色 请看一下代码 我的视图模型 public PaginationModel pagination { get { return _pagination; } set { _pagination = value; OnPropertyChanged("pagination"); } } 我的分页

我在ItemsControl分页种类控件中有一个按钮我在视图模型中有一个名为current_page的属性

我想将当前页面值与1/2/3的按钮内容进行比较,并想更改按钮的前景色

请看一下代码

我的视图模型

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的值绑定到属性,因为它不是依赖项属性。您可以通过创建一个自定义多值转换器来解决这个问题,该转换器检查页面是否相等

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值。有点奇怪,您当前的_页面是int类型,但是PageList是string类型的集合,这就是为什么我们需要转换第二个值的原因

在创建样式之前,在资源中创建转换器的实例,以便可以引用它

<local:PageEqualityToBooleanConverter x:Key="PageEqualityToBooleanConverter"/>
第一个绑定将找到父项控件以访问包含当前页面的视图模型。第二个绑定将绑定到相关按钮的数据上下文,即页面字符串。如果将PageList项类型更改为int,此选项仍然有效

建议 我想指出一些对代码的观察,这些观察可能会帮助您改进代码

正如我已经提到的,集合项类型与当前项属性类型不同似乎很奇怪。如果计划拥有比页中的页码更多的属性,请考虑使其为int或创建单独的页项视图模型。 您正在为按钮定义隐式样式,该样式将应用于范围中的所有按钮控件。如果您仅在分页控件中使用它,这可能没问题,但如果您打算在其他位置使用它,则不应将DataTrigger包含在其中,因为它仅特定于此数据上下文。基于此样式创建单独的样式。考虑一下BioNICCODE对此的评论。 正如@Andy在评论中指出的,a可能更适合paginator,因为它的项容器上有SelectedItem和IsSelected属性的概念,可以绑定到DataTrigger中,这就是您在这里尝试手动执行的操作。 值转换器解决方案 无法将DataTrigger的值绑定到属性,因为它不是依赖项属性。您可以通过创建一个自定义多值转换器来解决这个问题,该转换器检查页面是否相等

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值。有点奇怪,您当前的_页面是int类型,但是PageList是string类型的集合,这就是为什么我们需要转换第二个值的原因

在创建样式之前,在资源中创建转换器的实例,以便可以引用它

<local:PageEqualityToBooleanConverter x:Key="PageEqualityToBooleanConverter"/>
第一个绑定将找到父项控件以访问包含当前页面的视图模型。第二个绑定将绑定到相关按钮的数据上下文,即页面字符串。如果将PageList项类型更改为int,此选项仍然有效

建议 我想指出一些对代码的观察,这些观察可能会帮助您改进代码

正如我已经提到的,集合项类型与当前项属性类型不同似乎很奇怪。如果计划拥有比页中的页码更多的属性,请考虑使其为int或创建单独的页项视图模型。 您正在为按钮定义隐式样式,该样式将应用于范围中的所有按钮控件。如果您仅在分页控件中使用它,这可能没问题,但如果您打算在其他位置使用它,则不应将DataTrigger包含在其中,因为它仅特定于此数据上下文。基于此样式创建单独的样式。考虑一下BioNICCODE对此的评论。 正如@Andy在评论中指出的,a可能更适合paginator,因为它的项容器上有SelectedItem和IsSelected属性的概念,可以绑定到DataTrigger中,这就是您在这里尝试手动执行的操作。 DataTrigger的Value属性不能是数据绑定的

您应该做的是创建一个表示页面的类型,向其添加一个数字和IsCurrentPage属性,并将PageList的类型更改为ObservableCollection而不是ObservableCollection

然后,只要在页面列表中查找相应的页面,并在设置当前页面属性时从视图模型中设置其IsCurrentPage属性即可

您还应该确保PageList属性的getter不会在每次调用时创建新集合。

DataTrigger的Value属性不能进行数据绑定

您应该做的是创建一个表示页面的类型,添加一个数字,然后IsCurrentP 属性,并将页列表的类型更改为ObservableCollection,而不是ObservableCollection

然后,只要在页面列表中查找相应的页面,并在设置当前页面属性时从视图模型中设置其IsCurrentPage属性即可


您还应该确保PageList属性的getter不会在每次调用时创建一个新集合。

由于触发器不能触发按钮的属性,因此DataTrigger不应该是按钮的ControlTemplate的一部分,它是一个内部控件上下文,独立于任何数据类型。由于触发器在当前按钮的DataContext的属性上触发,因此DataTrigger必须位于按钮外部,它可以像在样式目标按钮中一样访问DataContext,或者在项目模板的DataTemplate中更好地访问DataContext。在这里,您所处的上下文专门针对特定的DataContext,即数据类型。您可以将其作为listbox而不是itemscontrol绑定到selecteditem的属性。使PageList成为viewmodels的列表,而不仅仅是字符串。将笔刷属性添加到该属性。或者使用转换器将数字转换为画笔。具有WordOrangeBush的fallbackvalue。由于触发器在触发按钮的属性时不起作用,因此DataTrigger不应是按钮的ControlTemplate的一部分,它是一个内部控件上下文,独立于任何数据类型。由于触发器在当前按钮的DataContext的属性上触发,因此DataTrigger必须位于按钮外部,它可以像在样式目标按钮中一样访问DataContext,或者在项目模板的DataTemplate中更好地访问DataContext。在这里,您所处的上下文专门针对特定的DataContext,即数据类型。您可以将其作为listbox而不是itemscontrol绑定到selecteditem的属性。使PageList成为viewmodels的列表,而不仅仅是字符串。将笔刷属性添加到该属性。或者使用转换器将数字转换为画笔。具有WordOrangeBush的后备值。