如何消除Switch语句?

时间:2013-09-22 17:53:34

标签: c# wpf xaml design-patterns windows-phone-8

我有一个标签控件,有3个标签页。在同一表格/视图上的此选项卡控件下方,我有3个图像控件。

基于选项卡的SelectedIndex,我需要更改3张以下图像的不透明度。

截至目前,我在Tab控件的SelectionChanged事件中有类似的内容:

switch (Tab.SelectedIndex)
{
     case 0:
         img1.Opacity= 1;
         img2.Opacity = 0.5;
         img3.Opacity  = 0.5;
         break;
     case 1:
         img1.Opacity = 0.5;
         img2.Opacity = 1;
         img3.Opacity  = 0.5;
         break;
     case 2:
         img1.Opacity = 0.5;
         img2.Opacity = 0.5;
         img3.Opacity = 1;
         break;
}

如何删除此switch语句?我应该在这里使用哪种设计模式?

6 个答案:

答案 0 :(得分:1)

您可以使用为instace here解释的状态设计模式。您将定义几个状态,然后根据条件决定当下应该使用哪些状态。

示例:

abstract class State
{
    abstract vod Apply(Form context);
}

class StateOne : State
{
    override void Apply(Form context)
    {
        img1.Opacity= 1;
        img2.Opacity = 0.5;
        img3.Opacity  = 0.5;
    }
}

您还可以将其与Factory方法设计模式相结合,以决定使用哪种状态。

static class StateFactory
{
    static State GetState(condition)
    {
        if(condition == something)
            return new StateOne();
        else ...
    }
}

这不会从你的代码中删除switch语句,但它至少会在合理的地方做合理的事情。

用法:

StateFactory.GetState(condition).Apply(this);

答案 1 :(得分:1)

我认为您可以使用Triggers在您的xaml中处理此问题。

此外,如果您希望此单元可测试,则应使用MVVM pattern,在properties for SelectedIndex, Opacities中定义ViewModel并将其绑定到xaml

答案 2 :(得分:1)

提取并注入。将视图更改逻辑(切换)提取到外部类/方法并将其注入视图:

public void HighlightImages(int selection, params Image[] images)
{
    switch (selection)
    {
        case 0:
            images[0].Opacity= 1;
            images[1].Opacity = 0.5;
            images[2].Opacity  = 0.5;
            break;
        case 1:
            images[0].Opacity = 0.5;
            images[1].Opacity = 1;
            images[2].Opacity  = 0.5;
            break;
        case 2:
            images[0].Opacity = 0.5;
            images[1].Opacity = 0.5;
            images[2].Opacity = 1;
            break;
    }
}

在选择更改的处理程序中,您只需将处理委托给注入的依赖项:

private void SelectedIndexChanged(object sender, EventArgs e)
{
    this.highlighter.HighlightImages(Tab.SelectedIndex, img1, img2, img3);
}

这样您就可以轻松测试不透明度变化逻辑,而无需实例化全面的视图控制。

答案 3 :(得分:0)

如果你有一堆你需要传递的任意数据......那么真的没有办法轻易绕过switch语句(这至少值得努力)。至少在代码可读性方面,我建议使用枚举。您可以像这样重构代码:

    switch ((ImageTypes)Tab.SelectedIndex)
    {
        case ImageTypes.TypeOne:
            img1.Opacity= 1;
            img2.Opacity = 0.5;
            img3.Opacity  = 0.5;
            break;
        case ImageTypes.TypeTwo:
            img1.Opacity = 0.5;
            img2.Opacity = 1;
            img3.Opacity  = 0.5;
            break;
        case ImageTypes.TypeThree:
            img1.Opacity = 0.5;
            img2.Opacity = 0.5;
            img3.Opacity = 1;
            break;
    }
    public enum ImageTypes
    {
        TypeOne,
        TypeTwo,
        TypeThree
    }

答案 4 :(得分:0)

这不会完全消除它,因为除了创造一个大的遗产之外没什么可做的,但这对于这种情况来说有点过分。

相反,你可以减小它的大小:

switch (Tab.SelectedIndex)
{
     img1.Opacity = 0.5;
     img2.Opacity = 0.5;
     img3.Opacity = 0.5;

     case 0:
         img1.Opacity += 0.5;
         break;
     case 1:
         img2.Opacity += 0.5;
         break;
     case 2:
         img3.Opacity += 0.5;
         break;
}

您可以使用方法减少代码冗余,因此每次要更改不透明度时都不必更改0.5。 (将0.5放在常数中也会很好):

switch (Tab.SelectedIndex)
{
     SetInitialOpacity(img1);
     SetInitialOpacity(img2);
     SetInitialOpacity(img3);

     case 0:
         IncreaseOpacity(img1);
         break;
     case 1:
         IncreaseOpacity(img2);
         break;
     case 2:
         IncreaseOpacity(img3);
         break;
}

private void SetInitialOpacity(Image image)
{
    image.Opacity = 0.5;
}


private void IncreaseOpacity(Image image)
{
    image.Opacity += 0.5;
}

答案 5 :(得分:0)

参考“jimmy-keen”所说的,这就是我想要的:

    public static void HighlightImages(int selection, params Image[] images)
    {
        for (int img = 0; img < images.Length; img++)
        {
            images[img].Opacity = (img == selection ? 1 : 0.5);
        }
    }