使用多个图像创建可缩放控件
Using multiple images to create a scalable control
问题
我需要制作使用图像作为背景的控件,可以是任何宽度而不扭曲图像。例如,如果我使用单个图像并将其拉伸,图像的圆角就会变形。
解决方案
Noxivs 给出的解决方案是使用带有三个图像的自定义 UserControl,两个边和一个被拉伸的中间。
将 SnapsToDevicePixels="True" 添加到 UserControl Grid 很重要,否则图像之间会出现单个像素间隙。
MainWindow.xaml
<Window x:Class="Testing.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ns="clr-namespace:Testing"
Title="MainWindow" Height="350" Width="525">
<Grid Name="MainGrid">
<ns:ScalableTextBox TextBoxText="Added in XAML" Width="120" Margin="0,0,0,100">
</ns:ScalableTextBox>
</Grid>
</Window>
MainWindow.xaml.cs
ScalableTextBox scalableTextBox = new ScalableTextBox();
scalableTextBox.TextBoxText = "Added in C#";
scalableTextBox.Width = 100;
MainGrid.Children.Add(scalableTextBox);
ScalableTextBox.xaml.cs
public partial class ScalableTextBox : UserControl
{
public ScalableTextBox()
{
InitializeComponent();
}
public string TextBoxText
{
get { return this.TextBoxName.Text; }
set { this.TextBoxName.Text = value; }
}
}
ScalableTextBox.xaml
<UserControl x:Class="Testing.ScalableTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="36" d:DesignWidth="50" Height="36" MinWidth="29">
<Grid>
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="pack://siteoforigin:,,,/Images/left.png" />
<Image Grid.Column="1" Stretch="Fill" Source="pack://siteoforigin:,,,/Images/center.png"/>
<Image Grid.Column="2" Source="pack://siteoforigin:,,,/Images/right.png" />
</Grid>
<TextBox Name="TextBoxName" VerticalAlignment="Center"
HorizontalAlignment="Center" Background="{x:Null}"
BorderBrush="{x:Null}" FontSize="12"/>
</Grid>
</UserControl>
再次感谢 Noxivs!
我不确定你想要什么但是:
- 我认为您可以在 XAML 中创建完全相同的图像设计
(无论大小,矢量都能保持您的风格)。
- 如何使用您的文本框创建您自己的控件用户 (0
不透明度)和任意数量的背景图像? (不太好)
这些只是建议。
编辑:
这是您的可缩放文本框:
我不得不拆分你的第一张图片。
http://i.stack.imgur.com/cGJ8u.png
http://i.stack.imgur.com/Fo4Oo.png
<UserControl x:Class="YourNamespace.ScalableTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Height="36" MinWidth="29">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="left.png" />
<Image Grid.Column="1" Source="center.png" Stretch="Fill"/>
<Image Grid.Column="2" Source="right.png" />
</Grid>
<TextBox VerticalAlignment="Center" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="14" FontFamily="Comic Sans MS" Margin="8,0"/>
</Grid>
<Window x:Class="YourNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ns="clr-namespace:_28400241"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ns:ScalableTextBox></ns:ScalableTextBox>
</Grid>
</Window>
我仍然认为在 XAML 中创建控件更好。
此致。
编辑 2:
动态加载图像(myGrid 是 window 的主网格,我在 ScalableTextBox 对象中命名了 3 个图像控件):
public MainWindow()
{
InitializeComponent();
ScalableTextBox tb = new ScalableTextBox();
tb.Width = 140;
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri("./left.png", UriKind.Relative);
src.EndInit();
tb.LeftImage.Source = src;
src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri("./center.png", UriKind.Relative);
src.EndInit();
tb.CenterImage.Source = src;
src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri("./right.png", UriKind.Relative);
src.EndInit();
tb.RightImage.Source = src;
Grid.SetRow(tb, 0);
Grid.SetColumn(tb, 0);
myGrid.Children.Add(tb);
}
我不确定你想要什么,但如果你只是想让图像显示为文本框的背景,你可以为文本框创建一个样式,修改 ControlTemplate 并在其中放置一个网格,包含图像。
例如(这只是为了让您了解我要解释的内容,而不是要实现的确切代码):
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="left.png" />
<Image Grid.Column="1" Source="center.png" Stretch="Fill"/>
<Image Grid.Column="2" Source="right.png" />
<ScrollViewer x:Name="ContentElement" Grid.Column="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
问题
我需要制作使用图像作为背景的控件,可以是任何宽度而不扭曲图像。例如,如果我使用单个图像并将其拉伸,图像的圆角就会变形。
解决方案
Noxivs 给出的解决方案是使用带有三个图像的自定义 UserControl,两个边和一个被拉伸的中间。
将 SnapsToDevicePixels="True" 添加到 UserControl Grid 很重要,否则图像之间会出现单个像素间隙。
MainWindow.xaml
<Window x:Class="Testing.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ns="clr-namespace:Testing"
Title="MainWindow" Height="350" Width="525">
<Grid Name="MainGrid">
<ns:ScalableTextBox TextBoxText="Added in XAML" Width="120" Margin="0,0,0,100">
</ns:ScalableTextBox>
</Grid>
</Window>
MainWindow.xaml.cs
ScalableTextBox scalableTextBox = new ScalableTextBox();
scalableTextBox.TextBoxText = "Added in C#";
scalableTextBox.Width = 100;
MainGrid.Children.Add(scalableTextBox);
ScalableTextBox.xaml.cs
public partial class ScalableTextBox : UserControl
{
public ScalableTextBox()
{
InitializeComponent();
}
public string TextBoxText
{
get { return this.TextBoxName.Text; }
set { this.TextBoxName.Text = value; }
}
}
ScalableTextBox.xaml
<UserControl x:Class="Testing.ScalableTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="36" d:DesignWidth="50" Height="36" MinWidth="29">
<Grid>
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="pack://siteoforigin:,,,/Images/left.png" />
<Image Grid.Column="1" Stretch="Fill" Source="pack://siteoforigin:,,,/Images/center.png"/>
<Image Grid.Column="2" Source="pack://siteoforigin:,,,/Images/right.png" />
</Grid>
<TextBox Name="TextBoxName" VerticalAlignment="Center"
HorizontalAlignment="Center" Background="{x:Null}"
BorderBrush="{x:Null}" FontSize="12"/>
</Grid>
</UserControl>
再次感谢 Noxivs!
我不确定你想要什么但是:
- 我认为您可以在 XAML 中创建完全相同的图像设计 (无论大小,矢量都能保持您的风格)。
- 如何使用您的文本框创建您自己的控件用户 (0 不透明度)和任意数量的背景图像? (不太好)
这些只是建议。
编辑:
这是您的可缩放文本框:
我不得不拆分你的第一张图片。 http://i.stack.imgur.com/cGJ8u.png http://i.stack.imgur.com/Fo4Oo.png
<UserControl x:Class="YourNamespace.ScalableTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Height="36" MinWidth="29">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="left.png" />
<Image Grid.Column="1" Source="center.png" Stretch="Fill"/>
<Image Grid.Column="2" Source="right.png" />
</Grid>
<TextBox VerticalAlignment="Center" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="14" FontFamily="Comic Sans MS" Margin="8,0"/>
</Grid>
<Window x:Class="YourNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ns="clr-namespace:_28400241"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ns:ScalableTextBox></ns:ScalableTextBox>
</Grid>
</Window>
我仍然认为在 XAML 中创建控件更好。
此致。
编辑 2:
动态加载图像(myGrid 是 window 的主网格,我在 ScalableTextBox 对象中命名了 3 个图像控件):
public MainWindow()
{
InitializeComponent();
ScalableTextBox tb = new ScalableTextBox();
tb.Width = 140;
BitmapImage src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri("./left.png", UriKind.Relative);
src.EndInit();
tb.LeftImage.Source = src;
src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri("./center.png", UriKind.Relative);
src.EndInit();
tb.CenterImage.Source = src;
src = new BitmapImage();
src.BeginInit();
src.UriSource = new Uri("./right.png", UriKind.Relative);
src.EndInit();
tb.RightImage.Source = src;
Grid.SetRow(tb, 0);
Grid.SetColumn(tb, 0);
myGrid.Children.Add(tb);
}
我不确定你想要什么,但如果你只是想让图像显示为文本框的背景,你可以为文本框创建一个样式,修改 ControlTemplate 并在其中放置一个网格,包含图像。
例如(这只是为了让您了解我要解释的内容,而不是要实现的确切代码):
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="left.png" />
<Image Grid.Column="1" Source="center.png" Stretch="Fill"/>
<Image Grid.Column="2" Source="right.png" />
<ScrollViewer x:Name="ContentElement" Grid.Column="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>