class 样式的绑定背景颜色

Binding Background Color of style from a class

在我的应用程序中,我有 ColorToBrushConverter.cs、ColorItem.cs 和一个包含一些颜色集合的方框页面,当用户单击任何颜色并返回主页时,它会保存到设置隔离存储中,然后我能够将我的堆栈面板的任何元素背景设置为从该颜色框页面中选择的颜色。

但问题是我有一种风格,我想要颜色绑定,所以我们可以从 c# 中做到这一点,还是从 class.

下面的 xaml 中使用颜色绑定

ColorToBrushConverter.cs

namespace CustomColorsPicker.Converters
{
    public class ColorToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null)
            {
                return new SolidColorBrush((Color)(value));
            } 
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
        throw new NotImplementedException();
        }
    }
}

ColorItem.cs

namespace ColorBox
{
    public class ColorItem
    {        
        public Color Color { get; set; }
    }
}

BoxPage.Xaml

包含颜色列表

xmlns:converters="clr-namespace:CustomColorsPicker.Converters"
<Page.Resources>
    <converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
</Page.Resources>

//////////

<ListBox Grid.Row="2" Name="listBox" ScrollViewer.VerticalScrollBarVisibility="Disabled" SelectionChanged="lstColor_SelectionChanged" Width="460" Height="770" Margin="0,20,0,0"> 
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel x:Name="item" Orientation="Horizontal" Margin="10,10,0,0">
                <Border CornerRadius="5" BorderThickness="2" BorderBrush="{Binding Color, Converter={StaticResource ColorToBrushConverter}}">
                    <Rectangle Fill="{Binding Color, Converter={StaticResource ColorToBrushConverter}}" Width="50" Height="50" />
                 </Border>
             </StackPanel>
         </DataTemplate>
     </ListBox.ItemTemplate>
</ListBox>

BoxPage.xaml.cs

//Constructor. list of colors
static uint[] uintColors =
{
    0xFFD9325D,
    0xFFFFFF00,0xFFFFE135,0xFFFFFF66,0xFFF8DE7E,0xFF008000,0xFF008A00            
};

public BoxPage()
{
    InitializeComponent();           
    this.Loaded += BoxPage_Loaded;
}

private async void BoxPage_Loaded(object sender, RoutedEventArgs e)
{
    List<ColorItem> item = new List<ColorItem>();
    for (int i = 0; i < 67; i++)
    {
        item.Add(new ColorItem() { Color = ConvertColor(uintColors[i])});
    };
    listBox.ItemsSource = item;
}

private void lstColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count > 0)
    {
        (Application.Current as App).CurrentColorItem = ((ColorItem)e.AddedItems[0]);                
    }
}

MainPage.xaml.cs

//Constructor
IsolatedStorageSettings ColourSettings = IsolatedStorageSettings.ApplicationSettings;

public MainPage()
{
    InitializeComponent();
    InitializeSettings();
}

private void InitializeSettings()
{
    if (!ColourSettings.Contains("LastColorItem"))
    {
        ColorItem item = new ColorItem();
        item.Color = Colors.Cyan;
        ColourSettings.Add("LastColorItem", item);                
    }
}


protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);
    ColourSettings["LastColorItem"] = _colorItem;
}

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    if (ColourSettings.Contains("LastColorItem"))
    {
        _colorItem = (ColorItem)ColourSettings["LastColorItem"];
    }

    ColorItem myColorItem = (Application.Current as App).CurrentColorItem;
    if (myColorItem != null)
    {
        _colorItem = (ColorItem)myColorItem;
    }

    MyFillStackPanel.Background = new SolidColorBrush(_colorItem.Color);
    MyCtrlPanelBorder.Background = new SolidColorBrush(_colorItem.Color);                       
}

MainPage.xaml

xmlns:converters="clr-namespace:CustomColorsPicker.Converters"
<Page.Resources>
    <converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
</Page.Resources>

在我的一种样式中,我想用上面的颜色绑定它,因为我无法在 c# 中执行或编辑样式

//SomeStyle
<DiscreteObjectKeyFrame.Value>
    <SolidColorBrush Color="{**i want to bind color here**}"/>
</DiscreteObjectKeyFrame.Value>

假设您的转换器工作正常,您的代码中实际缺少的是实际的绑定过程。

您的 ColorItem class(需要从接口 INotifyPropertyChanged 派生)必须声明 PropertyChanged 事件。 当您的 属性 颜色被修改时,您想引发一个事件,因此 UI 会收到 属性 颜色已更新的通知。

按照惯例,您可以通过调用一个与您的事件处理程序同名并以 "On" 为前缀的方法来执行此操作,因此您必须实现该方法 OnPropertyChanged,正如我所提到的,它负责实际引发 PropertyChanged 事件。

您可以通过多种方式定义此实现,但您可以在此处查看 Microsoft 自己的实现。 enter link description here

公开你的属性,

public ColorItem MyColor {get;set;}

因此,当您定义 {Binding ...} 时,CLR 将能够在运行时找到 属性。

在MainPage构造函数中,可以初始化这个属性

MyColor = new ColorItem();

并将页面的DataContext定义为:

this.DataContext = MyColor;

现在您应该可以让您的源使用您定义的代码更新目标。如果您打算让 UI 将修改传播到源上,您必须使用 Mode=TwoWay 定义绑定,因为绑定的默认模式是 模式=单向

编辑

public class ColorItem: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        public Color color
        {
            get
            {
                return _color;
            }
            set
            {
                _color = value;
                this.OnPropertyChanged();
            }
        }

        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            // Raise the PropertyChanged event, passing the name of the property whose value has changed.
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

公开 属性 并将其设置为页面的 DataContext。 然后通过 {Binding MyColor.color .... }

在 Binding 中引用它