如果两个对象的背景颜色匹配,如何生成新的背景颜色?

Posted

技术标签:

【中文标题】如果两个对象的背景颜色匹配,如何生成新的背景颜色?【英文标题】:How to generate new back colour if two object's back colour match? 【发布时间】:2019-05-11 17:11:20 【问题描述】:

我有一个相当简单的 WCF 程序,用户可以在其中单击两个按钮:ChangeBackGroundColourChangeButtonColour

WCF 服务从颜色列表中返回一个随机颜色,并且该字符串通过 switch case 语句指示两个对象的颜色。

但是,对象的颜色不能相同。如何阻止重复?

这是我的代码:

前端

public partial class Front_End : Form

    RandomColourServiceReference.RandomColoursServiceClient ws = null;
    string BackGroundColour  get; set; 
    string TextColour  get; set; 

    public Front_End()
    
        InitializeComponent();
    

    private void Front_End_Load(object sender, EventArgs e)
    
        ws = new RandomColourServiceReference.RandomColoursServiceClient();
    

    private void BtnChangeBack_Click(object sender, EventArgs e)
    
        BackGroundColour = ws.GenerateRandomColour();
        switch (BackGroundColour)
        
            case "Red":
                this.BackColor = Color.Red;
                break;
            case "Blue":
                this.BackColor = Color.Blue;
                break;
            case "Black":
                this.BackColor = Color.Black;
                break;
            case "Purple":
                this.BackColor = Color.Purple;
                break;
            case "Green":
                this.BackColor = Color.Green;
                break;
        
    

    private void BtnChangeButton_Click(object sender, EventArgs e)
    
        TextColour = ws.GenerateRandomColour();

        switch (TextColour)
        
            case "Red":
                btnChangeButton.BackColor = Color.Red;
                btnChangeBack.BackColor = Color.Red;
                break;
            case "Blue":
                btnChangeButton.BackColor = Color.Blue;
                btnChangeBack.BackColor = Color.Blue;
                break;
            case "Black":
                btnChangeButton.BackColor = Color.Black;
                btnChangeBack.BackColor = Color.Black;
                break;
            case "Purple":
                btnChangeButton.BackColor = Color.Purple;
                btnChangeBack.BackColor = Color.Purple;
                break;
            case "Green":
                btnChangeButton.BackColor = Color.Green;
                btnChangeBack.BackColor = Color.Green;
                break;
        
    

RandomColourService

public class RandomColoursService : IRandomColoursService

    public string GenerateRandomColour()
    
        //Declare and initialize a list of string colours
        List<String> colours = new List<String>();
        colours.AddRange(new String[] "Red", "Blue", "Green", "Pink", "Purple", "Black");

        //create new instance of random
        Random rand = new Random();

        //return a random colour in array
        return colours[rand.Next(0, colours.Count)];
    

IRandomColourService

[ServiceContract]
public interface IRandomColoursService

    [OperationContract]
    string GenerateRandomColour();

我觉得应该涉及一个 while 循环,但我不太确定。

或者也许我应该让 2 个对象从 wcf 返回,而不是只返回一个,然后检查它们在 wcf 中是否重复,如果是,则生成一个新对象? 所以它只会发送 2 种不同的颜色。那会是最好的吗?


*这是尝试添加更多属性后的更新代码

前端

public partial class Front_End : Form


    RandomColoursService.RandomColoursServiceClient ws = null;

    /*create two properties that can:385
    A. set the initial colours for the form objects. 
    B. be passed to wcf service as a used color to be removed from the list of colours that could potentially be returned next. */  
    Color BackGroundColour  get; set;  = Color.Blue;
    Color TextColour  get; set;  = Color.Red;
    Color ButtonColour  get; set;  = Color.Black;
    public Front_End()
    
        //objects are initilized with colours. 
        InitializeComponent();
        btnChangeBack.BackColor = ButtonColour;
        btnChangeButton.BackColor = ButtonColour;
        btnChangeText.BackColor = ButtonColour;
        this.BackColor = BackGroundColour;
        lblTitle.ForeColor = TextColour;
        btnChangeBack.ForeColor = TextColour;
        btnChangeButton.ForeColor = TextColour;
        btnChangeText.ForeColor = TextColour;

    

    private void Front_End_Load(object sender, EventArgs e)
    
        //create new instance of wcf service
        ws = new RandomColoursService.RandomColoursServiceClient();

    

    private void BtnChangeBack_Click(object sender, EventArgs e)
    
        //This list is populated with the with current colours
        List<Color> UsedColours = new List<Color>() TextColour, ButtonColour, BackGroundColour;
        //Call for another colour, pass in the current colour to be removed from list. 
        BackGroundColour = ws.GenerateRandomColour(UsedColours);
        //set object colour to returned colour
        this.BackColor = BackGroundColour;

    

   private void BtnChangeButton_Click(object sender, EventArgs e)
    
        //This list is populated with the with current colours
        List<Color> UsedColours = new List<Color>() TextColour, BackGroundColour, ButtonColour;
        //Call for another colour, pass in the current colour to be removed from list. 
        ButtonColour = ws.GenerateRandomColour(UsedColours);
        //set object colour to returned colour
        btnChangeButton.BackColor = ButtonColour;
        btnChangeBack.BackColor = ButtonColour;
        btnChangeText.BackColor = ButtonColour;



    

    private void BtnChangeText(object sender, EventArgs e)
    
        //This list is populated with the with current colours
        List<Color> UsedColours = new List<Color>()  BackGroundColour, ButtonColour, TextColour;
        //Call for another colour, pass in the current colour to be removed from list. 
        TextColour = ws.GenerateRandomColour(UsedColours);
        //set object colour to returned colour
        btnChangeButton.ForeColor = TextColour;
        btnChangeBack.ForeColor = TextColour;
        btnChangeText.ForeColor = TextColour;
        lblTitle.ForeColor = TextColour;

    


IRandomColoursService

[ServiceContract]
public interface IRandomColoursService

    [OperationContract]

    //As a parameter, pass in a list of coloured. 
    //The list will be populated with the current colours on the front end,
    //when a button is clicked a new call is made to wcf.
    Color GenerateRandomColour(List<Color> UsedColours);


RandomColoursService

    public class RandomColoursService : IRandomColoursService

    public Color GenerateRandomColour(List<Color> UsedColours)
    
        //This is a list of potential colours that wcf can send. 
        List<Color> Colours = new List<Color>()
        
            Color.Red, Color.Blue, Color.Black, Color.Green, Color.Indigo, Color.Orange
        ;

        //This is a list of available colours once the current object colours are removed from the list.
        List<Color> AvailableColours = Colours.Except(UsedColours).ToList();
        Random rand = new Random();
        return Colours[rand.Next(0, AvailableColours.Count)];
    



为了澄清,我应该在调用 wcf 时传递一个 UsedColours 列表。从颜色列表中扣除 UsedColors,然后可用颜色列表保存剩余的颜色。然后每次调用都应该返回可用颜色列表中的一个随机颜色?

我哪里出错了?

【问题讨论】:

【参考方案1】:

如果您的代码可以修改(包括接口),我建议进行以下更改

由于您有两个引用所选颜色的属性,您可以分配默认值并使用这些值来设置表单和按钮的初始颜色。

这些属性随后可用于引用 GenerateRandomColour([Color]) 方法无法选择的已使用颜色。 传递给方法的 Color 参数在随机选择一个新颜色之前从颜色列表中删除:


[ServiceContract]
public interface IRandomColoursService

    [OperationContract]
    Color GenerateRandomColour(Color UsedColor);


public class RandomColoursService : IRandomColoursService

    public Color GenerateRandomColour(Color UsedColor)
    
        List<Color> colours = new List<Color>()  
            Color.Red, Color.Blue, Color.Green, Color.Pink, Color.Purple, Color.Black
        ;
        colours.Remove(UsedColor);
        Random rand = new Random();
        return colours[rand.Next(0, colours.Count)];
    


RandomColourServiceReference.RandomColoursServiceClient ws = null;

Color BackGroundColour  get; set;  = Color.Red;
Color TextColour  get; set;  = Color.Black;

public Front_End()

    InitializeComponent();
    btnChangeButton.BackColor = TextColour;
    btnChangeBack.BackColor = TextColour;
    this.BackColor = BackGroundColour;


private void BtnChangeButton_Click(object sender, EventArgs e)

    TextColour = ws.GenerateRandomColour(BackGroundColour);
    btnChangeButton.BackColor = TextColour;
    btnChangeBack.BackColor = TextColour;


private void BtnChangeBack_Click(object sender, EventArgs e)

    BackGroundColour = GenerateRandomColour(TextColour);
    this.BackColor = BackGroundColour;

更新: 如果要添加更多控件和相关属性,请更改 GenerateRandomColour 方法,使其接受 List&lt;Color&gt; 而不是单个颜色引用。 (此处使用LINQ 的Except() 扩展方法来过滤使用另一个列表) 例如:

public Color GenerateRandomColour(List<Color> UsedColor)

    List<Color> colours = new List<Color>()  
        Color.Red, Color.Blue, Color.Green, Color.Pink, Color.Purple, Color.Black
    ;
    List<Color> AvailableColours = colours.Except(UsedColor).ToList();
    Random rand = new Random();
    return AvailableColours[rand.Next(0, AvailableColours.Count)];


Color BackGroundColour  get; set;  = Color.Black;
Color TextColour  get; set;  = Color.Red;
Color AnotherColour  get; set;  = Color.Green;

private void BtnChangeButton_Click(object sender, EventArgs e)

    List<Color> UsedColors = new List<Color>()  BackGroundColour, AnotherColour ;
    TextColour = ws.GenerateRandomColour(UsedColors);
    btnChangeButton.BackColor = TextColour;
    btnChangeBack.BackColor = TextColour;


//(...)

等等。

但是,如果有很多属性,这可能会变得太麻烦。 您可以构建一个专门的类,将颜色映射到控件(使用它们的引用或名称),然后用于与GenerateRandomColour() 方法交换信息。

【讨论】:

天哪。你可以有一个列表或一组颜色!?很高兴知道!我尝试扩展并添加第三个属性,以便有一个按钮来更改背景、按钮和文本颜色。我基本上只是添加了一个额外的参数,但 colours.Remove 只能与 1 个参数一起使用。知道如何从列表中删除 2 个项目吗?还是不能做? 列表可以包含任何内容。如果您需要更改更多属性,请参阅更新以了解可能的替代方法。此处使用List.Except(List) 扩展方法来过滤使用另一个列表。 我得到 “参数 1:无法从 'System.Collections.Generic.List' 转换为 'System.Drawing.Color'” 用于前端每个按钮单击方法的 UsedColors。我已经更新了服务参考,但仍然出现错误。通过代码它应该是所有 List 。任何想法?谢谢吉米。 好吧,再次检查一下 :) (我的意思是将您的代码与更新中的代码进行比较)。看起来您的 GenerateRandomColour() 方法试图返回 List&lt;Color&gt; 而不是 Color。或者类似的东西。 好的,吉米。这应该如何?感觉好像我已经尝试了所有的组合。 :P 虽然老实说我对我的导师这么说然后她告诉我我很愚蠢。如果您好心,我已经对原始代码进行了编辑!

以上是关于如果两个对象的背景颜色匹配,如何生成新的背景颜色?的主要内容,如果未能解决你的问题,请参考以下文章

如何拉伸 flex child 以使背景颜色与兄弟姐妹的高度匹配

如何将元素的背景颜色与 2 种半透明元素背景颜色匹配

如何将 UILabel 文本颜色与其背景匹配? [复制]

CNContactViewController 导航栏背景颜色与我的应用不匹配

如何更改 UITableViewCell 编辑按钮背景颜色?

如何在情节提要上更改标签栏背景颜色和标签栏项目颜色