In WPF , i create button on canvas. like this.
private void DrawBtnTag( List<ValPosCrt> tagPos)
{
int posNum = tagPos.Count;
StackPanel[] temp = new StackPanel[ posNum ];
Button[] btn = new Button[posNum];
for ( int i = 0 ; i < posNum ; i++ )
{
var btntemp = CheckButton(i);
Canvas.SetLeft( btntemp , tagPos [ i ].X );
Canvas.SetTop( btntemp , tagPos [ i ].Y );
cvsMap.Children.Add( btntemp );
btn [ i ] = btntemp;
}
}
private Button CheckButton( int i ) // done
{
var btn = new Button();
btn.Name = "btn" + i.ToString();
btn.Width = 20;
btn.Height = 20;
btn.VerticalAlignment = VerticalAlignment.Stretch;
btn.HorizontalAlignment = HorizontalAlignment.Stretch;
btn.Click += ClickIdx;
return btn;
}
but when i run this code and expand application size, button position is not updated.
Second image is expanded application size and small button that i created is act anchored object. I want to this button follow background Image.
Xaml code is just only this
<DockPanel Name="dckPanel" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border CornerRadius="6" BorderThickness="2" BorderBrush="RoyalBlue" DockPanel.Dock="Top" >
<Grid>
<Canvas Name="cvsMap" Grid.Column="0" ClipToBounds="True" Margin="15">
<Canvas.Background>
<ImageBrush x:Name="imgMap" Stretch="Uniform" RenderOptions.BitmapScalingMode="Fant" />
</Canvas.Background>
</Canvas>
</Grid>
</Border>
</DockPanel>
How can i fix this?
** update : Add TestCode , Fix Xaml Code.
This is test code for wpf project
Code Behind -
public partial class MainWindow : Window
{ public MainWindow() { InitializeComponent();
List<Point> inputdata = new List<Point>(); inputdata.Add( new Point( 250 , 250 ) ); inputdata.Add( new Point( 250 , 300 ) ); inputdata.Add( new Point( 300 , 250 ) ); inputdata.Add( new Point( 250 , 200 ) ); inputdata.Add( new Point( 200 , 250 ) ); DrawBtnTag( inputdata ); imgMap.ImageSource = createImg(); } private void DrawBtnTag( List<Point> tagPos ) // done { int posNum = tagPos.Count; StackPanel[] temp = new StackPanel[ posNum ]; Button[] btn = new Button[posNum]; for ( int i = 0 ; i < posNum ; i++ ) { var btntemp = CheckButton(i); Canvas.SetLeft( btntemp , tagPos [ i ].X ); Canvas.SetTop( btntemp , tagPos [ i ].Y ); cvsMap.Children.Add( btntemp ); btn [ i ] = btntemp; } } private Button CheckButton( int i ) // done { var btn = new Button(); btn.Name = "btn" + i.ToString(); btn.Width = 20; btn.Height = 20; btn.VerticalAlignment = VerticalAlignment.Stretch; btn.HorizontalAlignment = HorizontalAlignment.Stretch; return btn; } public BitmapSource createImg() { List<System.Windows.Media.Color> colors = new List<System.Windows.Media.Color>(); colors.Add( System.Windows.Media.Colors.Red ); colors.Add( System.Windows.Media.Colors.Blue ); BitmapPalette palette = new BitmapPalette(colors); System.Windows.Media.PixelFormat pf = System.Windows.Media.PixelFormats.Indexed1; int width = 128; int height = width; int stride = width/pf.BitsPerPixel; byte[] pixels = new byte[height*stride]; for ( int i = 0 ; i < height * stride ; ++i ) { if ( i < height * stride / 2 ) { pixels [ i ] = 0x00; } else { pixels [ i ] = 0xff; } } return BitmapSource.Create( width, height, 96, 96, pf, palette, pixels, stride); }
}
xaml code - => same as xaml code abaove. just put that dockpanel after window. like this window> .. here ../window>
The answer might be a bit long but it should work without modifications.
Basically:
Here is the modified XAML code:
<Canvas Name="cvsMap" Grid.Column="0" ClipToBounds="True" Margin="15" SizeChanged="cvsMap_SizeChanged">
<Canvas.Background>
<ImageBrush x:Name="imgMap" Stretch="Uniform" RenderOptions.BitmapScalingMode="Fant" />
</Canvas.Background>
</Canvas>
And then the code behind (copy/paste after your createImg function):
private void cvsMap_SizeChanged(object sender, SizeChangedEventArgs e)
{
double ratio = imgMap.ImageSource.Width / imgMap.ImageSource.Height;
foreach (Control ctrl in cvsMap.Children)
{
if (ctrl is Button)
{
newBtnPosition((Button)ctrl, ratio, e);
}
}
}
/// <summary>
/// Assign a new position to a ctrl contained into a canvas
/// </summary>
/// <param name="ctrl">control to modify</param>
/// <param name="ratio">ratio of the reference element</param>
/// <param name="e">SizeChanged of the container</param>
private void newBtnPosition(Control ctrl, double ratio, SizeChangedEventArgs e)
{
//Everythong is computed according to the reference element (ImageBrush)
Size oldImgSize, newImgSize;
//Avoid dividing by 0
if (e.PreviousSize.Width * e.PreviousSize.Height * e.NewSize.Width * e.NewSize.Height == 0) { return; }
oldImgSize = RefSize(ratio, e.PreviousSize);
newImgSize = RefSize(ratio, e.NewSize);
Point oldImgPos, newImgPos;
oldImgPos = new Point((e.PreviousSize.Width - oldImgSize.Width) / 2, (e.PreviousSize.Height - oldImgSize.Height) / 2);
newImgPos = new Point((e.NewSize.Width - newImgSize.Width) / 2, (e.NewSize.Height - newImgSize.Height) / 2);
//Retrieve the position of the control according to the ref element
Point ctrlPos = new Point((double)ctrl.GetValue(Canvas.LeftProperty) - oldImgPos.X,
(double)ctrl.GetValue(Canvas.TopProperty) - oldImgPos.Y);
//Compute the new position according to the reference element
ctrlPos.X*=newImgSize.Width / oldImgSize.Width;
ctrlPos.Y *= newImgSize.Height / oldImgSize.Height;
//Assign the new position according to the Canvas
ctrl.SetValue(Canvas.LeftProperty, ctrlPos.X + newImgPos.X);
ctrl.SetValue(Canvas.TopProperty, ctrlPos.Y + newImgPos.Y);
}
/// <summary>
/// Compute a element size, given a aspect ratio, a container size, and a Stretch="Uniform" behavior
/// </summary>
/// <param name="ratio">aspect ratio of the control</param>
/// <param name="containerSize">container size of the control</param>
/// <returns>new size</returns>
private Size RefSize(double ratio, Size containerSize)
{
double cH, cW;
cW = containerSize.Width;
cH = containerSize.Height;
if (cH * cW == 0) { return new Size(0, 0); }
if (cW / cH > ratio)
{
return new Size(cH * ratio, cH);
}
else
{
return new Size(cW, cW/ratio);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.