Как создать новый задний цвет, если два задних цвета совпадают? - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть довольно простая программа WCF, в которой пользователь может нажимать две кнопки:
ChangeBackGroundColour & ChangeButtonColour.

Служба WCF возвращает случайный цвет из списка цветов, и эта строка определяет цвет двух объектов с помощью оператора switch case.

Однако цвет объектов не можетбыть таким же.Как остановить дубликат?

Вот мой код:

Front_End

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 разных цвета.Это будет лучше?


* Вот обновленный код после попытки добавить дополнительные свойства

Front_End

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


}

Чтобы уточнить, я должен передать список UsedColours, когда я звоню wcf,Используемые цвета вычитаются из списка цветов, а затем список доступных цветов содержит то, что осталось.Один случайный цвет из списка доступных цветов должен быть возвращен за вызов?

Где я ошибся?

1 Ответ

0 голосов
/ 10 декабря 2018

Если ваш код может быть изменен (включая интерфейс), это изменения, которые я предлагаю :

Поскольку у вас есть два свойства, которые ссылаются наВыбранные цвета, вы можете назначить значения по умолчанию и использовать эти значения для установки начальных цветов формы и кнопок.

Эти свойства затем можно использовать для ссылки на уже используемый цвет, который нельзя выбрать методом 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<Color> вместо одной ссылки на Color.
( LINQ *1030* 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() метод.

...