时间:2015-11-29 08:37:36

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

我在Grid内有以下代码:

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

如何在代码中绑定TranslateTransform.XTranslateTransform.Y?我发现this问题,但解决方案适用于非嵌套依赖项属性。他们该怎么办?我不能考虑绑定到整个RenderTransform。我正在开发winrt app,因此多重绑定已经不在游戏中了。

1 个答案:

答案 0 :(得分:1)

这是绑定背后的代码。我没有使用转换器,因为我的X和Y被定义为double。为了进行正确的绑定,您必须使用dependecy属性或其他通知机制(如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。看起来像是这样的: running view

请记住,上次更新解决方案基于LayouTransform,并在每次按钮点击时重新构建视图(使其缩放)。 的问候,