【问题标题】:Getting binding of transform property from code behind从后面的代码中获取转换属性的绑定
【发布时间】:2015-11-29 08:37:35
【问题描述】:

我在Grid 内有以下代码:

<Grid.RenderTransform>
    <TranslateTransform
        X="{Binding X, Converter={StaticResource HorizontalPositionConverter}}"
        Y="{Binding Y, Converter={StaticResource VerticalPositionConverter}}"
    />
</Grid.RenderTransform>

如何在后面的代码中绑定TranslateTransform.XTranslateTransform.Y?我发现this 问题,但解决方案适用于非嵌套依赖属性。他们在的时候该怎么办?我不能考虑绑定到整个RenderTransform。我正在开发 winrt 应用程序,所以多绑定不在游戏中。

【问题讨论】:

    标签: c# xaml windows-runtime code-behind


    【解决方案1】:

    这里是绑定的代码。我没有使用转换器,因为我的 X 和 Y 被定义为双重。为了进行正确的绑定,您必须使用依赖属性或其他通知机制(如 INotifyPropertyChanged 实现)。这是绑定解决方案(不是 MVVM)背后的代码。我添加了按钮来测试移动。 1. XAML 代码:

    <Window x:Class="TransformBindingSoHelpAttempt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" x:Name="This">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.RenderTransform>
            <TranslateTransform
                X="{Binding ElementName=This, Path=X, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
                Y="{Binding ElementName=This, Path=Y, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
        </Grid.RenderTransform>
        <Button Content="Click" Width="100" Height="100" Click="ButtonBase_OnClick"></Button>
    </Grid>
    

    2. 后面的代码:

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        public static readonly DependencyProperty XProperty = DependencyProperty.Register(
            "X", typeof (double), typeof (MainWindow), new PropertyMetadata(default(double)));
    
        public double X
        {
            get { return (double) GetValue(XProperty); }
            set { SetValue(XProperty, value); }
        }
    
        public static readonly DependencyProperty YProperty = DependencyProperty.Register(
            "Y", typeof (double), typeof (MainWindow), new PropertyMetadata(default(double)));
    
        private static double _position;
    
        public double Y
        {
            get { return (double) GetValue(YProperty); }
            set { SetValue(YProperty, value); }
        }
    
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            X = ++_position;
            Y = _position;
        }
    }
    

    更新 1: 这是基于代码隐藏的解决方案,XAML 中没有绑定: 3. 代码背后:

        public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
    
    
        public static readonly DependencyProperty XProperty = DependencyProperty.Register(
            "X", typeof (double), typeof (MainWindow), new PropertyMetadata(default(double)));
    
        public double X
        {
            get { return (double) GetValue(XProperty); }
            set { SetValue(XProperty, value); }
        }
    
        public static readonly DependencyProperty YProperty = DependencyProperty.Register(
            "Y", typeof (double), typeof (MainWindow), new PropertyMetadata(default(double)));
    
        private static double _position;
    
        public double Y
        {
            get { return (double) GetValue(YProperty); }
            set { SetValue(YProperty, value); }
        }
    
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            X = ++_position;
            Y = _position;
        }
    
        private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
        {
            var grid = sender as Grid;
            if(grid == null) return;
            var transform = grid.RenderTransform as TranslateTransform;
            if (transform == null)
            {
                transform = InitTransformBinding();
                grid.RenderTransform = transform;
            }
            else
            {
                InitTransformBinding(transform);
            }
    
        }
    
        private TranslateTransform InitTransformBinding(TranslateTransform t = null)
        {
    
            var transform = t ?? new TranslateTransform();
            var xBinding = new Binding();
            xBinding.Source = this;
            xBinding.Path = new PropertyPath("X");
            xBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            xBinding.Mode = BindingMode.TwoWay;
            BindingOperations.SetBinding(transform, TranslateTransform.XProperty, xBinding);
            var yBinding = new Binding();
            yBinding.Source = this;
            yBinding.Path = new PropertyPath("Y");
            yBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            yBinding.Mode = BindingMode.TwoWay;
            BindingOperations.SetBinding(transform, TranslateTransform.YProperty, yBinding);
            return transform;
        }
    }
    

    4。 XAML 代码:

    <Window x:Class="TransformBindingSoHelpAttempt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" x:Name="This">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Loaded="FrameworkElement_OnLoaded">
        <Button Content="Click" Width="100" Height="100" Click="ButtonBase_OnClick"></Button>
    </Grid>
    

    更新 2,在此处单击每个按钮,您将缩放网格。 5.Xaml代码:

    Window x:Class="TransformBindingSoHelpAttempt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:transformBindingSoHelpAttempt="clr-namespace:TransformBindingSoHelpAttempt"
        Title="MainWindow" Height="350" Width="525" x:Name="This">
    <Window.DataContext>
        <transformBindingSoHelpAttempt:MainViewModel/>
    </Window.DataContext>
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListView ItemsSource="{Binding Items}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate DataType="{x:Type transformBindingSoHelpAttempt:ItemDataContext}">
                                <Grid>
                                    <Grid.RenderTransform>
                                        <ScaleTransform
                                                ScaleX="{Binding X, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                                ScaleY="{Binding Y, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                                    </Grid.RenderTransform>
                                    <Button Content="{Binding ButtonContent}" Command="{Binding ButtonCommand}"/>
                                </Grid>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>
    </Grid>
    

    6.查看模型:

        public class MainViewModel:BaseObservableObject
    {
        public MainViewModel()
        {
            Items = new ObservableCollection<ItemDataContext>(new List<ItemDataContext>
            {
                new ItemDataContext{ButtonContent = "A", X = 1.0, Y = 1.0},
                new ItemDataContext{ButtonContent = "B", X = 1.0, Y = 1.0},
                new ItemDataContext{ButtonContent = "C", X = 1.0, Y = 1.0},
                new ItemDataContext{ButtonContent = "D", X = 1.0, Y = 1.0},
            });
        }
        public ObservableCollection<ItemDataContext> Items { get; set; }
    }
    
    public class ItemDataContext:BaseObservableObject
    {
        private ICommand _buttonCommand;
        private object _buttonContent;
        private double _x;
        private double _y;
    
        public double X
        {
            get { return _x; }
            set
            {
                _x = value;
                OnPropertyChanged();
            }
        }
    
        public double Y
        {
            get { return _y; }
            set
            {
                _y = value;
                OnPropertyChanged();
            }
        }
    
        public ICommand ButtonCommand
        {
            get { return _buttonCommand ?? (_buttonCommand = new DelegateCommand(Target)); }
        }
    
        public object ButtonContent
        {
            get { return _buttonContent; }
            set
            {
                _buttonContent = value;
                OnPropertyChanged();
            }
        }
    
        private void Target(object obj)
        {
            X += 0.2;
            Y += 0.2;
        }
    }
    

    7。它是怎样的:

    请记住,最后一次更新解决方案是基于 LayouTransform 并在每次按钮单击时重新构建视图(使其可缩放)。 问候,

    【讨论】:

    • 好的,好点。但我认为我的任务有点困难,因为我的Grid 嵌入在一个列表中(ItemsControl)。我没有在我的问题中提供此信息,因为我认为这可能并不重要。您有什么想法吗?我该如何针对这种情况修改您的解决方案?
    • @pt12lol 为什么这很重要?每个网格都有自己的 X 和 Y 位置吗?你有视图模型吗?
    • 我的ItemsControl 有自己的视图模型,由许多Grid 的视图模型组成,其中包含相对的XY 坐标。后面的代码应该按ItemsControl 的大小缩放它们,因为它是 UI 逻辑。网格只是网格 - 它们没有 XY 依赖属性。由于某些原因,将Grid 设置为UserControl 是不可能的。
    • @pt12lol 我可以理解,您需要从每个 ItemsControl 项目的视图模型中按 X 和 Y 坐标移动网格。对吗?
    • 是的。然后我想在后面的代码中缩放XY。而且我不介意将它们放在后面的代码中。但我不知道怎么做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2011-02-15
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多