简体   繁体   English

Silverlight-更改动态创建的按钮文本的颜色

[英]Silverlight - Changing button text color created dynamically

I am trying to change a button text color of dynamically created buttons on a Silverlight form using ViewModel. 我正在尝试使用ViewModel更改Silverlight表单上动态创建的按钮的按钮文本颜色。 The problem I face is, when I change the color of a button text, all the buttons will get effected. 我面临的问题是,当我更改按钮文本的颜色时,所有按钮都会生效。 Since, the buttons are dynamically created, I can't have a control on it. 由于按钮是动态创建的,因此无法对其进行控制。

I was suggested to write a ForegroundColor property into Model and then attach to the button, I tried as you see in code, but couldn't do much about it. 建议我在模型中编写一个ForegroundColor属性,然后将其附加到按钮上,就像您在代码中看到的那样,但是对此却无能为力。

Could you see as what I am doing and help me with your suggestions as I am not sure, I am doing it right way. 您不确定我正在做什么,并且不确定(我不确定),我会以正确的方式帮助您提出建议。

Thanks 谢谢

Model 模型

namespace Web.Models
{
  [DataContract(IsReference = true)]
  public class Sales
  {
    [DataMember]
    public int SalesId { get; set; }
    [DataMember]
    public int ShowOrder { get; set; }
    [DataMember]
    public bool Active { get; set; }
    [DataMember]
    public bool Regurgitate { get; set; }

    [DataMember]
    public int ForegroundColor { get; set; }

    public Sales(Salese result)
    {
        SalesId = result.SalesId;
        ShowOrder = result.ShowOrder;
        Active = result.Active;
        Regurgitate = result.Regurgitate;            

        if (SalesId == 12)
        {
            var bytes = System.BitConverter.GetBytes(ForegroundColor);
            Color btnColor = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]);

            SolidColorBrush myBrush = new SolidColorBrush(btnColor);
        }
   }
}

} }

ViewModel 视图模型

private Brush _foregroundColor = new SolidColorBrush(Colors.Black); 

public override void Loaded()
{
    OnMainOutcome();
}


public Brush ForegroundColor
{
   get { return _foregroundColor; }
   set
   {
       if (_foregroundColor == value) return;
       _foregroundColor = value;                

       OnPropertyChanged("ForegroundColor");
    }
 }

 private void OnMainOutcome()
 {
    var selectedSalesId = (int)OutcomeCommand.CommandParameter;
    CurrentSubOutcomes = GetCurrentSubOutcomes(selectedSalesId);

    foreach (var index in CurrentOutcomes)
    {
       if (index.OutcomeId == 12)        
          ForegroundColor = new SolidColorBrush(Colors.Red);
       else
          ForegroundColor = new SolidColorBrush(Colors.Black);
    }
 }

XAML Edited XAML编辑

 <controls:ChildWindow.Resources>
    <converters:NumericToColorConverter x:Key="NumericToColorConverter"/>
</controls:ChildWindow.Resources>

 <ListBox Grid.Row="1" Height="Auto" MinHeight="200" Width="160" Margin="2,2,2,2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=CurrentOutcomes}" Background="{x:Null}" BorderBrush="{x:Null}">
      <ListBox.ItemTemplate>
          <DataTemplate>
               <Button Height="30" Width="150" HorizontalAlignment="Center" Content="{Binding Outcome}" CommandParameter="{Binding SalesOutcomeId }" Command="{Binding Source={StaticResource ViewModel}, Path=OutcomeCommand}" Foreground="{Binding Source={StaticResource ViewModel}, Converter={StaticResource NumericToColorConverter}, Path=ForegroundColor}" />
          </DataTemplate>
      </ListBox.ItemTemplate>
 </ListBox>

Converter Class NEW 转换器类NEW

  using System;
  using System.Windows.Data;
  using System.Windows.Media;
  using System.Windows;

  namespace Converters
  {
      public class NumericToColorConverter : IValueConverter
      {
        static readonly SolidColorBrush RED_BRUSH = new SolidColorBrush(Colors.Red);
        static readonly SolidColorBrush BLUE_BRUSH = new SolidColorBrush(Colors.Blue);

        public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
        {
           //Int32 id = System.Convert.ToInt32(value);

           //LinearGradientBrush brush = new LinearGradientBrush();
           //brush.StartPoint = new Point(0, 1);
           //brush.EndPoint = new Point(0, 0);
           //brush.GradientStops.Add(new GradientStop()
           //{
           //    Color = Colors.White,
           //    Offset = 0
           //});
           //brush.GradientStops.Add(new GradientStop()
           //{            
           //    Color = Color.FromArgb(
           //        200,
           //        System.Convert.ToByte((id * 103) % 256),
           //        System.Convert.ToByte((id * 157) % 256),
           //        System.Convert.ToByte((id * 233) % 256)
           //    ),
           //    Offset = 1
           //});

           //return brush;
           var OutcomeId = (int)value;

           if (OutcomeId == 12)
           {
              return RED_BRUSH;
           }
           else
           {
              return BLUE_BRUSH;
           }
    }

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

} }

Your listbox displays a list of Sales , but each item is templated to bind button foreground to single property in the VM. 您的列表框显示Sales的列表,但是每个项目都经过模板化以将按钮前景绑定到VM中的单个属性。 Create MyBrush property in your Sales class and bind to it. 在您的Sales类中创建MyBrush属性并绑定到它。

namespace Web.Models
{
  [DataContract(IsReference = true)]
  public class Sales
  {
    [DataMember]
    public int SalesId { get; set; }
    [DataMember]
    public int ShowOrder { get; set; }
    [DataMember]
    public bool Active { get; set; }
    [DataMember]
    public bool Regurgitate { get; set; }

    [DataMember]
    public int ForegroundColor { get; set; }

    [DataMember]
    public SolidColorBrush MyBrush { get; set; }

    public Sales(Salese result)
    {
        SalesId = result.SalesId;
        ShowOrder = result.ShowOrder;
        Active = result.Active;
        Regurgitate = result.Regurgitate;            

        if (SalesId == 12)
        {
            var bytes = System.BitConverter.GetBytes(ForegroundColor);
            Color btnColor = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]);

            MyBrush = new SolidColorBrush(btnColor);

        }
   }
}

<ListBox Grid.Row="1" Height="Auto" MinHeight="200" Width="160" Margin="2,2,2,2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=CurrentOutcomes}" Background="{x:Null}" BorderBrush="{x:Null}">
      <ListBox.ItemTemplate>
          <DataTemplate>
               <Button Height="30" Width="150" HorizontalAlignment="Center" Content="{Binding Outcome}" CommandParameter="{Binding SalesOutcomeId }" Command="{Binding Source={StaticResource ViewModel}, Path=OutcomeCommand}" Foreground="{Binding MyBrush}"  />
          </DataTemplate>
      </ListBox.ItemTemplate>
 </ListBox>

You bind the Foreground to a value on a StaticResource so all buttons will bind to this same value. 您将Foreground绑定到StaticResource上的值,以便所有按钮都将绑定到该相同值。

You can either create a specific "ButtonForegroundConverter" or you can add the Brush property to the item level viewmodel that also has the Outcome property which you already bind to the Content of the button. 您可以创建特定的“ ButtonForegroundConverter”,也可以将Brush属性添加到项目级别的视图模型中,该模型还具有已经绑定到按钮的ContentOutcome属性。 Then the button xaml will look something like this: 然后按钮xaml将如下所示:

<Button ...
        Content="{Binding Outcome}" 
        Foreground="{Binding OutcomeForegroundBrush}" 
        ...
        />

If you are binding directly to an entity, then adding properties like that would not be a good idea, so the example above assumes you have a intermediate viewmodel or controller on which you could add properties like that. 如果直接绑定到实体,则添加这样的属性不是一个好主意,因此上面的示例假定您具有一个中间视图模型或控制器,可以在其上添加这样的属性。

If you choose to use a converter it would look something like this: 如果您选择使用转换器,它将看起来像这样:

<Button ...
        Content="{Binding Outcome}" 
        Foreground="{Binding OutcomeId, Converter={StaticResource OutcomeToForegroundConverter}}" 
        ...
        />

And the converter: 和转换器:

namespace MyConverters {

    public sealed class OutcomeToColorConverter : IValueConverter {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {

            // We must have a valid integer value, double check bindings
            if (value == null) {
                throw new ArgumentNullException("value", 
                    "Please make sure the value is not null.");
            }

            var OutcomeId = (int)value;

            if (OutcomeId == XXX) { 
                return RED_BRUSH; 
            }
            else {
                return BLUE_BRUSH;
            }
        }

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

        static readonly SolidColorBrush RED_BRUSH = new SolidColorBrush(Colors.Red);

        static readonly SolidColorBrush BLUE_BRUSH = new SolidColorBrush(Colors.Blue);
    }
}

Remember to declare the resource: 记住声明资源:

<myconverters:OutcomeToForegroundConverter x:Key="OutcomeToForegroundConverter" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM