2017-11-10 92 views
-1

我有框,當選中時,我希望按鈕是真實的。如果所有複選框都未選中,則按鈕爲false。現在我遇到的問題是試圖查看他們是否有辦法在一個代碼中完成所有操作,而不是爲所有框輸入。我只包括前2個盒子,因爲所有盒子都是一樣的。 我是一個noob,這是從youtube和你的論壇學習C#的2-3天。C#複選框冗餘

private void boxChrome_CheckedChanged(object sender, EventArgs e) 
    { 
     if (boxChrome.Checked == true) 
      butInstall.Enabled = true; 
     else if 
      (boxChrome.Checked == false & boxAdobeReader.Checked == false & boxESET.Checked == false & boxiTunes.Checked == false & boxQuicktime.Checked == false & boxTeamviewer.Checked == false & boxWinrar.Checked == false & boxVLC.Checked == false) 
      butInstall.Enabled = false; 
    } 

    private void boxAdobereader_CheckedChanged(object sender, EventArgs e) 
    { 
     if (boxAdobeReader.Checked == true) 
      butInstall.Enabled = true; 
     else if 
      (boxChrome.Checked == false & boxAdobeReader.Checked == false & boxESET.Checked == false & boxiTunes.Checked == false & boxQuicktime.Checked == false & boxTeamviewer.Checked == false & boxWinrar.Checked == false & boxVLC.Checked == false) 
      butInstall.Enabled = false; 
    } 
    private void butInstall_Click(object sender, EventArgs e) 
    { 
    } 
+0

請注意'visual-studio'標籤是爲* Visual Studio問題保留的。從標籤:「如果您有關於Visual Studio特性和功能的特定問題,請使用此標籤,而不僅僅是關於您的代碼的問題」 – Amy

+3

爲什麼不讓所有複選框觸發相同的事件。然後,該事件將檢查所有需要更改按鈕的複選框。 –

+0

我會如何寫下來?對不起,這是所有這些新的 – infamous

回答

1

這取決於你的意思是所有的CheckBox什麼。讓我假設所有的CheckBox直接在表單中(而不是表單中的其他容器)。

在這種情況下,你可以寫一個通用的函數像下面

private static bool IsOneChecked(Control parent) { 
    return parent.Controls.OfType<CheckBox>().Any(box => box.Checked); 
} 

此功能會告訴你,如果至少具有一個CheckBox檢查與否。您可以使用它的返回值來啓用或禁用Button像下面

butInstall.Enabled = IsOneChecked(this); 

this代表包含所有CheckBox容器的實例。你可以把它根據你Form是如何佈局out. In case the複選框spans multiple containers, you can expand the IsOneChecked function to look for all the relevant CheckBox`

+0

對不起,「所有複選框」是表單中的所有框。您的答案與我在本網站找到的表單類似,但我無法理解。 – infamous

+0

@infamous你的評論是什麼意思..?如果你不理解它,那麼我建議你閱讀lambda表達式並理解控件類 – MethodMan

+0

比parent.Controls.Cast更好().Any(...)'是'parent .Controls.OfType ().Any(cb => cb.Checked)' –

5

適應現在我在試圖鍵入它,看是否做到這一點的一種方式都在同一個代碼,而不是問題爲所有箱子。我只包括前2個盒子,因爲所有盒子都是一樣的。

如果你多次輸入相同的代碼,你的直覺就是錯誤的東西是正確的,對你有良好的直覺很好。

處理這件事的方法是抽象的代碼的方法:

private void CheckedChanged(CheckBox box) 
{ 
    if (box.Checked == true) 
     butInstall.Enabled = true; 
    else if 
     (boxChrome.Checked == false & 
     boxAdobeReader.Checked == false & 
     boxESET.Checked == false & 
     boxiTunes.Checked == false & 
     boxQuicktime.Checked == false & 
     boxTeamviewer.Checked == false & 
     boxWinrar.Checked == false & 
     boxVLC.Checked == false) 
     butInstall.Enabled = false; 
} 
private void boxChrome_CheckedChanged(object sender, EventArgs e) => 
    CheckChanged(boxChrome); 

private void boxAdobereader_CheckedChanged(object sender, EventArgs e) => 
    CheckChanged(boxAdobeReader); 

所有權利。我們可以做得更好嗎?哦,天哪,是的。

首先:在C#中只有newbs說

if (box.Checked == true) 

這意味着「如果這是真的,這件事是真的,那麼」,這是瘋了。只是說:「如果這件事是真的,那麼」

if (box.Checked) 

如果這是真的,那麼它是已經真正。你不需要檢查真值是否等於真。

同樣,只有newbs說

boxChrome.Checked == false 

如果你想知道如果事情是假的,使用NOT操作:

!boxChrome.Checked 

好了,所以現在我們有

private void CheckedChanged(CheckBox box) 
{ 
    if (box.Checked) 
     butInstall.Enabled = true; 
    else if (
     !boxChrome.Checked & !boxAdobeReader.Checked & 
     !boxESET.Checked & !boxiTunes.Checked & 
     !boxQuicktime.Checked & !boxTeamviewer.Checked & 
     !boxWinrar.Checked & !boxVLC.Checked)) 
     butInstall.Enabled = false; 
} 

這樣好多了。

我們可以做得更好嗎?當然!我們可以注意到「這些東西都是假的?」與「這些事情之一是否屬實是錯誤的嗎?」

private void CheckedChanged(CheckBox box) 
{ 
    if (box.Checked) 
     butInstall.Enabled = true; 
    else if (
     !(boxChrome.Checked | boxAdobeReader.Checked | 
     boxESET.Checked | boxiTunes.Checked | 
     boxQuicktime.Checked | boxTeamviewer.Checked | 
     boxWinrar.Checked | boxVLC.Checked)) 
     butInstall.Enabled = false; 
} 

所以這樣更容易閱讀。我注意到你也可以使用||而不是|,雖然在這種情況下它確實沒有什麼區別。

我們可以做得更好嗎?當然。我們真的想在這裏檢查什麼?我們試圖表達「沒有選中任何框?」的概念。所以我們可以使用LINQ序列操作符來回答這個問題。做一個字段包含您的箱子:

private CheckBox[] boxes; 

在您的形式加載方法,初始化場:

... 
boxes = { boxChrome, boxAdobeReader, ... } 
... 

,現在我們可以使用這個:

private void CheckedChanged(CheckBox box) 
{ 
    if (box.Checked) 
     butInstall.Enabled = true; 
    else if (!boxes.Any(box => box.Checked)) 
     butInstall.Enabled = false; 
} 

現在的代碼讀取像它的意圖。 如果選中了特定框,則啓用該按鈕;如果沒有任何複選框,則禁用該按鈕「。嘗試找到一種讓您的代碼像其意圖一樣閱讀的方法。它會更短,更易於理解,這將更有可能是正確的。

而且總是問自己:「我可以做的更好?」例如,我們可以自動生成複選框集?我對Vikhram的回答評論給出了很好的建議。

+0

這是一個很棒的答案,非常感謝你!這是思考過程和做同樣事情的不同方式的一個很好的演練。 – Taegost

+0

這就是這樣一個詳細的答案,你竭盡全力給我一些指點。先生,謝謝你。我還沒有嘗試過,但會給這個鏡頭併發布我的結果! – infamous

0

這個問題有很多種解決方法,但是這裏有一個想法:創建一個複選框列表,當任何時候更新的時候,更新主複選框,你可以在列表中檢查選中的內容,如果你添加一個複選框,你只需要添加它的名單。

var checkBoxes = new List<CheckBox>(); 
checkBoxes.Add(boxAdobeReader); 
... // add the others. 

private void UpdateMasterCheckBoxState(){ 
    masterButton.IsChecked = checkboxes.Any((cbox) => cbox.IsChecked == true); 
} 

private void anyCheckBox_CheckedChanged(object sender, EventArgs e) 
{ 
    UpdateMasterCheckBoxState(); 
} 

然後在XAML中,他們都可以使用此處理

<CheckBox Click="anyCheckbox_CheckedChanged">AdobeReader</Checkbox> 

,或者如果你需要不同的處理每一個複選框他們可以調用UpdateMasterCheckBoxState()在每個處理程序結束。

private void AdobeCheckBox_CheckedChanged(object sender, EventArgs e) 
{ 
    DoAdobeOnlyStuff(); 
    UpdateMasterCheckBoxState(); 
}