0

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

但问题是我有一种我想要颜色绑定的样式,所以我们可以从 c# 中做到这一点,或者在下面的类中使用 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();
        }
    }
}

颜色项.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);                       
}

主页.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>
4

1 回答 1

1

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

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

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

您可以通过多种方式定义此实现,但您可以在此处查看 Microsoft 自己的实现。 在此处输入链接描述

暴露你的财产,

public ColorItem MyColor {get;set;}

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

在 MainPage 构造函数中,您可以初始化此属性

MyColor = new ColorItem();

并将页面的DataContext定义为:

this.DataContext = MyColor;

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

编辑

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 中引用它

于 2017-11-29T08:33:29.190 回答