Binding Background Color of style from a class

2019-06-10 05:56发布

in my app i have ColorToBrushConverter.cs, ColorItem.cs and a box page which contain some collection of colors when user click on any of color and back to mainpage it save to settings isolated storage then i able to set my stackpanel any any element background to choosed color from that colorbox page.

But Problem is i have a style in which i want color binding so can we do it from c# or use color binding in xaml from below class.

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

contains list of color

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>

In One of my style i want to bind it with above color because i am unable to do or edit style in c#

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

1条回答
Anthone
2楼-- · 2019-06-10 06:31

Assuming your converter is working correctly, what is actually missing in your code is the actual Binding process.

Your ColorItem class (which needs to derive from the interface INotifyPropertyChanged) has to declare the PropertyChanged event. When your property Color gets modify you want to raise an event, so the UI gets notified that the property Color has been updated.

You do that on convention by calling a method with the same name as your eventhandler prefixed by "On", therefore you would have to implement the method OnPropertyChanged, which as I've mentioned would be responsible for actually raising the PropertyChanged event.

There are many ways from which you can define this implementation, but you can look here to see an implementation from Microsoft themselves. enter link description here

Expose your property,

public ColorItem MyColor {get;set;}

so when you define your {Binding ...} the CLR will be able to find the property during Runtime.

In the MainPage constructor, you can initialize this property

MyColor = new ColorItem();

And define the DataContext of the page as:

this.DataContext = MyColor;

Now you should be able to have your source update the target with the code which you have defined. If you intend to have your UI to propagate modifications onto the source you have to define the Binding with Mode=TwoWay, since the default mode for Binding is Mode=OneWay

Edit

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));
        }
    }

Expose the property and set it as the DataContext of your page. Then reference it in the Binding by {Binding MyColor.color .... }

查看更多
登录 后发表回答