【问题标题】:Applying a style to all child elements of a certain (named) stackpanel(or control)将样式应用于某个(命名)堆栈面板(或控件)的所有子元素
【发布时间】:2017-07-09 16:50:48
【问题描述】:

我试图简单地定义第二个堆栈面板(根堆栈面板中的两个)的所有矩形元素的填充,所需的填充为白色。由于堆栈面板没有 ItemTemplate,我尝试将其替换为 ItemsControl,然后将其封装。当我看到 ItemsControl 没有 Orientation 属性时,堆栈面板的封装就出现了。

无论如何,子矩形仍然没有被白色填充...... >.

(我也在尝试对事件绑定做同样的事情,就像 How to set an event function via a style?天)

<Window x:Class="RegenboogDragDrop.WindowRegenboog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WindowRegenboog" Height="350" Width="525">
<Window.Resources>
    <Style TargetType="{x:Type Rectangle}">
        <Setter Property="Height" Value="50"></Setter>
        <Setter Property="Width" Value="50"></Setter>
        <Setter Property="Margin" Value="5"></Setter>
        <Setter Property="Stroke" Value="Black"></Setter>
        <Setter Property="StrokeThickness" Value="3"></Setter>
    </Style>

</Window.Resources>
    <StackPanel>
    <StackPanel Margin="0,50" Orientation="Horizontal" HorizontalAlignment="Center">
        <Rectangle Fill="Yellow" MouseMove="Rectangle_MouseMove"></Rectangle>
        <Rectangle Fill="Orange" MouseMove="Rectangle_MouseMove"></Rectangle>
        <Rectangle Fill="Red" MouseMove="Rectangle_MouseMove"></Rectangle>
        <Rectangle Fill="Blue" MouseMove="Rectangle_MouseMove"></Rectangle>
        <Rectangle Fill="Green" MouseMove="Rectangle_MouseMove"></Rectangle>
        <Rectangle Fill="Violet" MouseMove="Rectangle_MouseMove"></Rectangle>
        <Rectangle Fill="Indigo" MouseMove="Rectangle_MouseMove"></Rectangle>
    </StackPanel>
    <ItemsControl Name="DropZone" HorizontalAlignment="Center">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Rectangle Fill="White"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>

        <StackPanel Orientation="Horizontal">
        <Rectangle Name="dropRed" Fill="White"/>
        <Rectangle Name="dropOrange" MouseMove="Rectangle_MouseMove" DragDrop.DragEnter="Rectangle_DragEnter" DragDrop.DragLeave="Rectangle_DragLeave" DragDrop.Drop="Rectangle_Drop" AllowDrop="True"></Rectangle>
        <Rectangle Name="dropYellow" Fill="White" MouseMove="Rectangle_MouseMove" DragDrop.DragEnter="Rectangle_DragEnter" DragDrop.DragLeave="Rectangle_DragLeave" DragDrop.Drop="Rectangle_Drop" AllowDrop="True"></Rectangle>
        <Rectangle Name="dropGreen"></Rectangle>
        <Rectangle Name="dropBlue"></Rectangle>
        <Rectangle Name="dropIndigo"></Rectangle>
        <Rectangle Name="dropViolet"></Rectangle>
        </StackPanel>
    </ItemsControl>
    <Button Name="ButtonCheck" Content="Check volgorde" Margin="5,50"></Button>
</StackPanel>

如果你想试试,后面的代码:(在第二行,第三个方块可以通过拖放接收颜色,而第二个有所有事件,但没有我需要的填充我正在努力让它拥有)(DutchVarsToEnglish:rechthoek 表示正方形,kleur 表示颜色,gesleepteKleur 表示 draggedColor,sleep 表示拖动)

https://defuse.ca/b/c19ncFwllWIpSRe6I0cclp(我不知道如何折叠 C# sn-p 就像这里的 js sn-p https://meta.stackexchange.com/questions/70885/collapse-code-snippets-in-answers :S 所以 pastebin 链接到代码隐藏)

【问题讨论】:

    标签: c# wpf wpf-controls wpf-style


    【解决方案1】:

    在 StackPanel 的资源中声明一个默认的矩形样式:

    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="Rectangle">
                <Setter Property="Fill" Value="White"/>
            </Style>
        </StackPanel.Resources>
    
        <Rectangle .../>
        ...
    </StackPanel>
    

    如果您在元素树中还有另一个默认的矩形样式,您可以将您的“本地默认样式”基于该样式,即样式的BasedOn 属性,例如

    <StackPanel.Resources>
        <Style TargetType="Rectangle" BasedOn="{StaticResource {x:Type Rectangle}}">
            <Setter Property="Fill" Value="White"/>
        </Style>
    </StackPanel.Resources>
    

    【讨论】:

    • 一个优雅的解决方案,一旦我接受答案,你就会得到我的支持(然后我将有 15 个代表),但是在这种情况下,我正在尝试学习如何做一件事(stackpanel 的样式子元素)所以这对我来说是一个 hack。我们可以想象有第三排盒子需要灰色作为填充物(比如说,做一个反向彩虹)。我想知道如何在没有黑客攻击的情况下做到这一点(即创建一个特殊的矩形子类型或该范围内的东西)
    • 不确定您所说的“黑客”是什么意思。对于父元素的子元素样式,这是一种方式。否则,您必须在某些顶级资源字典中创建带有 x:Key 的样式,并将它们显式分配给元素的 Style 属性。
    • aaaah 是的,我刚刚看到您的意思,您正在 StackPanel.Resources 中执行此操作!我如何在这里使用 BasedOn="..." 让它融入上述风格。
    • 好的,想通了&lt;Style TargetType="{x:Type Rectangle}" BasedOn="{StaticResource {x:Type Rectangle}}"&gt; &lt;Setter Property="Fill" Value="White"/&gt; &lt;/Style&gt;你能把它添加到你的答案中吗?我会接受的!
    【解决方案2】:

    您可以定义一个具有Fill 属性的类:

    public class Item
    {
        public Brush Fill { get; set; }
    }
    

    并将ItemsControlItemsSource 属性设置为此类对象的集合:

    public partial class WindowRegenboog : Window
    {
        public WindowRegenboog()
        {
            InitializeComponent();
            DropZone.ItemsSource = new List<Item> { new Item { Fill = Brushes.Red }, new Item() { Fill = Brushes.Yellow } };
        }
    }
    

    然后将ItemTemplateRectangleFill 属性绑定到Fill 源属性:

    <ItemsControl Name="DropZone" HorizontalAlignment="Center">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Rectangle Fill="{Binding Fill}" Width="200" Height="200"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    这样,您只需将源集合中项目的Fill 属性设置为不同的画笔,即可更改RectangleFill 颜色。

    【讨论】:

    • 我很欣赏 +1 的努力和巧妙的绑定。但是,为了他人的利益,我会接受克莱门斯的最佳实践解决方案。我不应该涉足 ItemTemplates,它们在我的情况下无法按预期工作,即使处理程序值上的 Visual Studio 错误也会使事情和样式复杂化,这似乎是一种更清晰的简洁方法。
    • +1?你好像忘记投票了。无论如何,如果您希望能够分别控制每个 Retangle 元素的填充,则使用隐式样式将不起作用。当您在 XAML 中处理任何类型的项目集合时,将 ItemsControl 与 ItemTemplate 和数据绑定一起使用是最佳实践。
    • 现在我的大脑(因缺乏睡眠而精疲力竭)无法完全理解为什么你的方法会更好。据我了解,您创建了一个自定义窗口类,并且以某种方式创建了一个没有基/继承/只有一个属性的项目类,然后您执行DropZone.ItemsSource=new List&lt;Item&gt; {new Item{Fill=Brushes.Red }, new Item(){Fill=Brushes.Yellow}}; (颜色可能稍后会变为动态),我没有完全理解。以我的卑微经验,我猜大部分其他开发者不会,这迫使我在非 KISS 的危险后核末日荒地设置中穿线。
    • (啊,是的,我很抱歉,我一定是在 15 岁之前分心或点击了。修复!)
    猜你喜欢
    • 2018-03-16
    • 2016-08-22
    • 2014-12-08
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多