WPF C#带有参数的设置样式 [英] WPF c# setting style with parameters

查看:65
本文介绍了WPF C#带有参数的设置样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种使用参数分配样式(大多数只是文本)并分配给指定块的方法

I'm looking for a way to assign style with parameters(most of them just text) and assign to specified blocks

<StackPanel Orientation="Horizontal">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock x:Name="field1" Text="Field1"/>
        </StackPanel>
    </StackPanel>
    <StackPanel>
        <Button BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock  FontSize="10" Text="Default" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBlock x:Name="field2" Text="Field2"/>
        </StackPanel>
    </StackPanel>
    <StackPanel>
        <Button  BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="10" Text="RCC" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBlock x:Name="field3" Text="Field3"/>
        </StackPanel>
    </StackPanel>
    <Rectangle Width="1" Fill="Black" Height="42" VerticalAlignment="Center"/>
    <StackPanel Orientation="Horizontal">
        <Button  BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="10" Text="Custom" Foreground="#FFCFCFCF" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
        <TextBox Width="90" Height="15"/>
        <Button  BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="10" Text="Apply" Foreground="#FFCFCFCF" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
    </StackPanel>
</StackPanel>

有3个TextBlocks(field1,field2,field3),现在可以通过任何方式传递参数了(参数是字符串类型),并转到此模板,并且此模板是通过循环生成的。以及如何做?当然,我可以使用c#进行所有操作,但我认为只需创建field(stackpanel)并分配参数就会容易得多。

There is 3 TextBlocks(field1,field2,field3), now is there any way to pass parameters(parameters are string type), to this template, and this template is generated through loop. And how to do it? Of course I could make everything in c# but thought it would be much easier just create field(stackpanel) and assign parameters

<stackpanel Style="{StaticResource mystyle}" param1="hello" param2="this" param3="world"/>

如果可能的话,这将是完美的。除非有更好的一个。谢谢您的帮助。

This would be perfect if its possible to make this way. Unless there is better one. Thanks for help.

推荐答案

您可以声明自己的样式和控件模板,并额外使用DependencyProperties。

You can by declaring your own Styles and Control templates with additional use of DependencyProperties.

从本质上讲,DependencyProperty是您要公开的自定义属性的自定义类的声明,您可以在xaml输入期间将其公开,也可以将其应用于样式模板。

A DependencyProperty is basically a declaration on your own custom class of your own custom property that you want to expose available during xaml entry and can also be applied to your style templates.

完成后,您就可以定义样式,并为此指定大量资源。将您的依赖项属性作为{TemplateBinding}包含到自定义属性中。

Once that is done, you then define your style, plenty of resources on that. Include your dependency properties as {TemplateBinding} to your custom properties.

然后将新类的实例添加到表单中,并指定要使用的样式。我有一个示例,显示了同一课上两种样式的利用率。我首先开始使用全新的WPF应用程序。在MainWindow.xaml.cs中,我根据UserControl类型定义了自己的类(该类可以容纳您嵌套的任何其他控件)。我添加了3个依赖项属性,以反映您要实现的3个可能的文本值。

Then add instance of your new class to your form, and specify which style to use. I have a sample showing utilization of TWO styles under the same class. I first started with a brand new WPF application. In the MainWindow.xaml.cs, I defined my own class based on a type of UserControl (which can then hold any other control(s) such as you have nested). I added 3 Dependency Properties to reflect 3 possible text values you want to implement.

public class MyControl : UserControl
{
    public static readonly DependencyProperty MyText1Property =
        DependencyProperty.Register("MyText1", typeof(string),
        typeof(MyControl), new UIPropertyMetadata(""));

    public string MyText1
    {
        get { return (string)GetValue(MyText1Property); }
        set { SetValue(MyText1Property, value); }
    }


    public static readonly DependencyProperty MyText2Property =
        DependencyProperty.Register("MyText2", typeof(string),
        typeof(MyControl), new UIPropertyMetadata(""));

    public string MyText2
    {
        get { return (string)GetValue(MyText2Property); }
        set { SetValue(MyText2Property, value); }
    }


    public static readonly DependencyProperty MyText3Property =
        DependencyProperty.Register("MyText3", typeof(string),
        typeof(MyControl), new UIPropertyMetadata(""));

    public string MyText3
    {
        get { return (string)GetValue(MyText3Property); }
        set { SetValue(MyText3Property, value); }
    }
}

接下来,我的应用程序名称是StackOverflow,用于示例,下面是整个MainWindow.xaml。组件的澄清遵循代码。

Next, my application name is StackOverflow for sample purposes, and in the following is the entire MainWindow.xaml. Clarification of components follows code.

<Window.Resources>
    <Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle1">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myApp:MyControl}" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{TemplateBinding MyText1}"/>
                        <TextBlock Text="{TemplateBinding MyText2}"/>
                        <TextBlock Text="{TemplateBinding MyText3}"/>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myApp:MyControl}" >
                    <StackPanel Orientation="Horizontal" Grid.Row="0">
                        <TextBlock Text="{TemplateBinding MyText1}"/>
                        <StackPanel>
                            <Button BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock  FontSize="10" Text="Default" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                <TextBlock Text="{TemplateBinding MyText2}"/>
                            </StackPanel>
                        </StackPanel>

                        <StackPanel>
                            <Button  BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock FontSize="10" Text="RCC" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                <TextBlock Text="{TemplateBinding MyText3}"/>
                            </StackPanel>
                        </StackPanel>
                        <Rectangle Width="1" Fill="Black" Height="42" VerticalAlignment="Center"/>
                        <StackPanel Orientation="Horizontal">
                            <Button  BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock FontSize="10" Text="Custom" Foreground="#FFCFCFCF" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                            <TextBox Width="90" Height="15"/>
                            <Button  BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock FontSize="10" Text="Apply" Foreground="#FFCFCFCF" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                        </StackPanel>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <!-- NOW, we can expand the custom properties-->
    <Style TargetType="{x:Type myApp:MyControl}" BasedOn="{StaticResource MyControlStyle}" />



</Window.Resources>


<Grid Height="150">
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>

    <myApp:MyControl MyText1="First String" MyText2="Second String" MyText3="Third String" 
        Style="{StaticResource MyControlStyle}"/>

    <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="1"/>

    <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="2"
        Style="{StaticResource MyControlStyle1}"/>

</Grid>

声明,我添加了

    xmlns:myApp="clr-namespace:StackOverflow"

这基本上表明,在此xaml文件中,我看到的前缀为 myApp,类似于使用StackOverflow;命令,就像在代码中一样。因此,现在我可以访问xaml的自定义类或该命名空间中的其他内容。

this basically states that when within this xaml file, I see a prefix of "myApp", it is similar to a "using StackOverflow;" command as if in code. So now I have access to the custom class(es) or other things within that namespace to the xaml.

接下来,我开始为自定义声明自己的样式 MyControl类通过

Next I start to declare my own "style" for the custom MyControl class via

<Window.Resources>
    <Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle1">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myApp:MyControl}" >

...

您可能想要如果您处理整个应用程序中使用的许多样式/模板,则可以创建单独的ResourceDictionary。请注意, Syle和自定义 ControlTemplate均基于 myApp:MyControl类结构。现在,我可以使用控件模板中的 MyText1, MyText2, MyText3元素。

You might want to create a separate ResourceDictionary if you deal with many styles / templates used throughout your app. Notice the "Syle" and custom "ControlTemplate" are based on the "myApp:MyControl" class structure. Now, I can make use of my "MyText1", "MyText2", "MyText3" elements within the control template.

x:Key = MyControlStyle1就像通过给定名称创建变量,以便在需要明确说明要使用哪种样式时可以使用它。第一种样式只是为了说明以下三个点:MyText属性可用,并且Text从

The x:Key="MyControlStyle1" is like creating a variable by given name so it can be used if you need to explicitly say which style to use. This first style is just to show the point that the 3 "MyText" properties are available and the Text is getting its value from the

Text="{TemplateBinding MyText1}"  

控制模板绑定到的类(因此,TemplateBinding) 。

Class that the control template is bound to (hence TemplateBinding).

一旦您掌握了基础知识,便可以使用嵌套堆栈面板(即较低的

Once you get the basics working, then you can glorify your template as you have with your nested stack panels which is the lower

<Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle"> 

用不同的x:键名声明。

declaration by a different x:Key name.

现在,所以您不必显式地继续为控件添加xaml并说...顺便说一句,使用这种显式的MyControlStyle样式,我将得到以下内容

Now, so you don't have to explicitly keep adding xaml for your control and say... by the way, use this explicit style of MyControlStyle, I have the following

<Style TargetType="{x:Type myApp:MyControl}" BasedOn="{StaticResource MyControlStyle}" />

指示何时看到目标类型 MyControl,则默认将样式设置为 MyControlStyle,我不必一直记住这样做。

indicating whenever you see a target type of "MyControl", default the style to the "MyControlStyle" so I don't have to keep remembering to do it.

最后实现它的使用。代码的末尾有一个简单的Grid控件,其中包含3行。

Finally implementing its use. The end of the code has a simple Grid control with 3 rows.

<myApp:MyControl MyText1="First String" MyText2="Second String" MyText3="Third String" 
            Style="{StaticResource MyControlStyle}"/>

        <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="1"/>

        <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="2"
            Style="{StaticResource MyControlStyle1}"/>

请注意,我可以显式声明要使用的样式的第一个实例。第二个没有默认的显式样式,但是第三个实例明确声明使用简化的 MyControlStyle1,这只是并排的3个文本块,表明您可以拥有一个类,并根据需要使其外观有所不同。

Notice the first instance I CAN explicitly declare the style to be used. The second has no explicit style as per the default, but the third instance explicitly states to use the simplified "MyControlStyle1" which was just the 3 textblocks side-by-side showing that you can have one class and make it look differently as needed.

每个问题/评论的修订。

如果您基于这些控件构建循环并动态添加它们,您只需在代码中分别设置属性。由于CLASS已经声明,所以性能应该不会很重要,您只需要在列表中再添加一个即可。

If you are building these controls based on a loop and dynamically adding them, you would just set the properties respectively in the code. Performance should not be significant because the CLASS is already declared, you are just adding one more into your list.

foreach( var oneThing in YourListOfToBeAddedItems )
{
   var mc = new MyControl();
   mc.MyText1 = oneThing.TextFieldUsedForField1;
   mc.MyText2 = oneThing.FieldForSecondText;
   mc.MyText3 = oneThing.ThirdTextBasisForDisplay;
   // Now, add the "mc" to whatever your control is
   // can't confirm this line below as I dont know context
   // of your form and dynamic adding.
   YourWindowGridOrOtherControl.Controls.Add( mc );
}

此外,由于定义了默认样式,因此无需显式声明控件的样式。

Also, since the default style was defined, I would not need to explicitly declare the "Style" for the control.

这篇关于WPF C#带有参数的设置样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆