首页 文章

在窗口调整大小时保持画布元素相对于背景图像的位置

提问于
浏览
1

我试图在我的画布中相对于我的背景定位元素 .

窗口重新调整大小,保持纵横比 . 背景用窗口大小拉伸 .

问题是一旦窗口重新调整大小,元素位置就不正确 . 如果窗口重新调整大小,元素将稍微调整它们的大小并且仍然处于正确的位置,但是如果窗口被重新调整大小以使其大小加倍,则定位完全关闭 .

到目前为止,我尝试使用 Grid ,但它也无济于事 . 这是XAML

<Window x:Class="CanvasTEMP.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow"  ResizeMode="CanResizeWithGrip" SizeToContent="WidthAndHeight" MinHeight="386" MinWidth="397.5" Name="MainWindow1"
    xmlns:c="clr-namespace:CanvasTEMP" Loaded="onLoad" WindowStartupLocation="CenterScreen" Height="386" Width="397.5" WindowStyle="None" AllowsTransparency="True" Topmost="True" Opacity="0.65">

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Canvas Height="77" Width="218">
                <Label Content="{Binding OwnerData.OwnerName}" Height="36" Canvas.Left="8" Canvas.Top="55" Width="198" Padding="0" HorizontalAlignment="Left" HorizontalContentAlignment="Center" VerticalAlignment="Center"/>
            </Canvas>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas>
                    <Canvas.Background>
                    <ImageBrush ImageSource="Resources\default_mapping.png" Stretch="Uniform"/>
                    </Canvas.Background>
            </Canvas>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding OwnerData.left}" />
            <Setter Property="Canvas.Top" Value="{Binding OwnerData.top}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

用于数据绑定的类

public class Owner : INotifyPropertyChanged
{
    public double _left;
    public double _top;

    public string OwnerName { get; set; }
    public double top { get { return _top; }
        set
        {
            if (value != _top)
            {
                _top = value;
                OnPropertyChanged();
            }
        }
    }
    public double left
    {
        get { return _left; }
        set
        {
            if (value != _left)
            {
                _left = value;
                OnPropertyChanged();
            }
        }
    }

    public string icon { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = "none passed")
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class ForDisplay
{
    public Owner OwnerData { get; set; }
    public int Credit { get; set; }
}

这里是每秒运行一次的代码,以保持元素相对于窗口大小的位置

items[0].OwnerData.left = this.Width * (10 / Defaul_WindowSize_Width); 
            items[0].OwnerData.top = this.Height * (55 / Defaul_WindowSize_Height);

默认情况下,10和50是首次初始化窗口时使用的 Canvas.LeftCanvas.Top .

如果有人能指出我做错了什么,我将不胜感激 .

1 回答

  • 0

    你需要attache属性:

    public static readonly DependencyProperty RelativeProperty = DependencyProperty.RegisterAttached("Relative", typeof(double), typeof(MyControl));
    
        public static double GetRelative(DependencyObject o)
        {
            return (double)o.GetValue(RelativeProperty);
        }
    
        public static void SetRelative(DependencyObject o, double value)
        {
            o.SetValue(RelativeProperty, value);
        }
    

    并添加转换器:

    public class RelativePositionConverter : IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
                var rel = (double)values[0];
                var width = (double)values[1];
                return rel * width;
            }
    
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    

    当你将孩子添加到画布时,你需要这样:

    var child = new Child();
                SetRelative(child, currentPosition / ActualWidth);
                var multiBinding = new MultiBinding { Converter = new RelativePositionConverter() };
                multiBinding.Bindings.Add(new Binding { Source = child, Path = new PropertyPath(RelativeProperty) });
                multiBinding.Bindings.Add(new Binding { Source = canvas, Path = new PropertyPath(ActualWidthProperty) });
                BindingOperations.SetBinding(child, LeftProperty, multiBinding);
                Children.Add(child);
    

    如果需要,可以更改Canvas的相对值

相关问题