代码之家  ›  专栏  ›  技术社区  ›  DavidN

避免wpf中的重复(干燥后)

  •  4
  • DavidN  · 技术社区  · 16 年前

    考虑以下两个xaml片段(它们在文件中并排排列):

    <Button
        x:Name="BuyButton"
        Margin="0,0,1,1"
        IsEnabled="{Binding CanBuy}"
        >
        <StackPanel
            DataContext="{Binding Product}">
            <TextBlock
                Foreground="Red"
                Text="BUY" />
            <TextBlock
                Foreground="Red"
                Text="{Binding BuyPrice}" />
        </StackPanel>
        </Button>
    
    <Button
        x:Name="SellButton"
        Margin="0,0,1,1"
        IsEnabled="{Binding CanSell}"
        >
        <StackPanel
            DataContext="{Binding Product}">
            <TextBlock
                Foreground="Red"
                Text="SELL" />
            <TextBlock
                Foreground="Red"
                Text="{Binding SellPrice}" />
        </StackPanel>
    </Button>
    

    如何删除wpf中的重复?我有大约4次使用(这里显示了2次)这种类型的按钮,他们是80%相同,如果不是更多。我可以把它提取到一个用户控件中,然后在它上面加上几个DPS,然后我会有一个控件,但是我担心我会开始用大量的用户控件乱扔我的代码库(我有很多这样的“一次性”情况)。我不喜欢这里的datatemplate解决方案,因为我仍然需要两个模板,这两个模板会重复代码。在不创建一堆模板/控件的情况下,有没有办法让代码枯燥无味?

    4 回复  |  直到 16 年前
        1
  •  3
  •   Joel Cochran    16 年前

    控件模板可能工作:

    <ControlTemplate x:Key="ButtonControlTemplate1" TargetType="{x:Type Button}">
    <StackPanel Height="Auto" Width="Auto">
        <TextBlock Text="{TemplateBinding Content}" Foreground="Red"/>
        <TextBlock Text="{TemplateBinding Tag}" Foreground="Red"/>
    </StackPanel></ControlTemplate>  
    

    我使用templatebinding来获取两个可变的数据片段。现在,当您创建按钮时,应用模板并设置对元素的绑定:

    <Button x:Name="BuyButton"
        Margin="0,0,1,1"
        IsEnabled="{Binding CanBuy}"
        Template="{DynamicResource ButtonControlTemplate1}"
        Content="Button" 
        Tag="{Binding BuyPrice}"/>
    

    唯一缺少的是datacontext:只需在两个按钮上方的容器中设置它。

    我没有特别尝试过,但似乎应该有效。我选择上面的“tag”是因为我需要第二个元素来绑定。我很想看到不同的建议。

    您可能还希望将foregroundcolor=“red”类型的内容打破为一种样式。

        2
  •  2
  •   Bas Bossink    16 年前

    我没有别的办法,但我不同意你关于一次性控制的论点。在我看来,这可以归结为在大量重复代码和少量重复代码之间进行选择,并使用一些相当具体的控件。如果这是简单的代码,那么当遇到几个相同的代码块时,您可能不会再想一想如何执行提取方法,为什么这段代码现在是xaml,这会使您的决定有所不同?

        3
  •  2
  •   Robert Macnee    16 年前

    如果你的目标只是为了减少重复,你可以通过使用样式和在父元素上设置公共附加属性来消除很多重复:

    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Margin" Value="0,0,1,1"/>
            </Style>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Foreground" Value="Red"/>
                <Setter Property="DataContext" Value="{Binding Product}"/>
            </Style>
        </StackPanel.Resources>
        <Button x:Name="BuyButton" IsEnabled="{Binding CanBuy}">
            <StackPanel>
                <TextBlock Text="BUY"/>
                <TextBlock Text="{Binding BuyPrice}"/>
            </StackPanel>
        </Button>
        <Button x:Name="SellButton" IsEnabled="{Binding CanSell}">
            <StackPanel>
                <TextBlock Text="SELL"/>
                <TextBlock Text="{Binding SellPrice}"/>
            </StackPanel>
        </Button>
    </StackPanel>
    

    注意,这最终是更多的代码…这就是为什么“3罢工,然后重构”是经验法则。

        4
  •  0
  •   Soviut    16 年前

    将其分离为用户控件。干原则和重构在任何平台上都应该得到同样的对待。