wpf - 从代码中添加 setter
wpf - add setter from code
我尝试从代码中添加按钮并向其添加触发器和 setters。我想创建这样的按钮:
<Button Height="25" Width="100" Name="TestColorButton" Margin="10, 5, 0, 0">
<TextBlock Text="{Binding Text, ElementName=ColorTextBox}"></TextBlock>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{Binding Fill, ElementName=NormalRectangle}"/>
<Setter Property="Template"> <!-- I need this setter -->
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding Fill, ElementName=MouseOverRectangle}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{Binding Fill, ElementName=ClickRectangle}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
我找到了除一个 setter 之外的所有方法。我通过评论检查了它。我试了很多次,我只得到这样的东西:
ContentPresenter contentPresenter = new ContentPresenter
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
Border border = new Border();
var binding = new Binding("Background");
binding.RelativeSource = new RelativeSource(RelativeSourceMode.Self);
BindingOperations.SetBinding(border, BackgroundProperty, binding);
border.Child = contentPresenter;
ControlTemplate controlTemplate = new ControlTemplate(typeof (Button));
Setter templateSetter = new Setter(TemplateProperty, controlTemplate);
style.Setters.Add(templateSetter);
我知道它行不通,但我不知道如何做。
模板可以通过代码轻松添加。这里有一个带有标签的例子。
// create the label with some context
var lbl = new Label() { DataContext = new ImageData(imagePath) };
// control template i want to put on the label
ControlTemplate labelLayout = new ControlTemplate();
// will be my main container that will be by template later on
FrameworkElementFactory grdContainer = new FrameworkElementFactory(typeof(Grid));
grdContainer.Name = "myContainer";
// another element but ill put it in the grid (template)
FrameworkElementFactory myImage = new FrameworkElementFactory(typeof(Image));
// some bindings and setters
myImage.SetBinding(Image.SourceProperty, new Binding("ImagePath"));
myImage.SetValue(Image.HorizontalAlignmentProperty, HorizontalAlignment.Center);
myImage.SetValue(Image.HeightProperty, height);
myImage.SetValue(Image.WidthProperty, double.NaN);
myImage.SetValue(Image.SnapsToDevicePixelsProperty, true);
// add the image to the grid
grdContainer.AppendChild(myImage);
// set the visual layout of the template to be the grid (main container)
labelLayout.VisualTree = grdContainer;
// set the template (line you are looking for mostly)
lbl.Template = labelLayout;
我尝试从代码中添加按钮并向其添加触发器和 setters。我想创建这样的按钮:
<Button Height="25" Width="100" Name="TestColorButton" Margin="10, 5, 0, 0">
<TextBlock Text="{Binding Text, ElementName=ColorTextBox}"></TextBlock>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{Binding Fill, ElementName=NormalRectangle}"/>
<Setter Property="Template"> <!-- I need this setter -->
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding Fill, ElementName=MouseOverRectangle}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{Binding Fill, ElementName=ClickRectangle}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
我找到了除一个 setter 之外的所有方法。我通过评论检查了它。我试了很多次,我只得到这样的东西:
ContentPresenter contentPresenter = new ContentPresenter
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
Border border = new Border();
var binding = new Binding("Background");
binding.RelativeSource = new RelativeSource(RelativeSourceMode.Self);
BindingOperations.SetBinding(border, BackgroundProperty, binding);
border.Child = contentPresenter;
ControlTemplate controlTemplate = new ControlTemplate(typeof (Button));
Setter templateSetter = new Setter(TemplateProperty, controlTemplate);
style.Setters.Add(templateSetter);
我知道它行不通,但我不知道如何做。
模板可以通过代码轻松添加。这里有一个带有标签的例子。
// create the label with some context
var lbl = new Label() { DataContext = new ImageData(imagePath) };
// control template i want to put on the label
ControlTemplate labelLayout = new ControlTemplate();
// will be my main container that will be by template later on
FrameworkElementFactory grdContainer = new FrameworkElementFactory(typeof(Grid));
grdContainer.Name = "myContainer";
// another element but ill put it in the grid (template)
FrameworkElementFactory myImage = new FrameworkElementFactory(typeof(Image));
// some bindings and setters
myImage.SetBinding(Image.SourceProperty, new Binding("ImagePath"));
myImage.SetValue(Image.HorizontalAlignmentProperty, HorizontalAlignment.Center);
myImage.SetValue(Image.HeightProperty, height);
myImage.SetValue(Image.WidthProperty, double.NaN);
myImage.SetValue(Image.SnapsToDevicePixelsProperty, true);
// add the image to the grid
grdContainer.AppendChild(myImage);
// set the visual layout of the template to be the grid (main container)
labelLayout.VisualTree = grdContainer;
// set the template (line you are looking for mostly)
lbl.Template = labelLayout;