使用 .NET 4.0 对“链接”变量(顶部/左侧和高度/宽度)进行双向绑定

Posted

技术标签:

【中文标题】使用 .NET 4.0 对“链接”变量(顶部/左侧和高度/宽度)进行双向绑定【英文标题】:TwoWay binding on "linked" variables (Top/Left & Height/Width) with .NET 4.0 【发布时间】:2012-03-08 07:17:58 【问题描述】:

我在切换到 .NET Framework 4.0 时遇到了一个问题。 我有一个窗口,它在其顶部/左侧和宽度/高度属性上使用双向绑定。

当我需要更改视图模型时出现问题。

更改底层ViewModel后,在我的viewModel对应的propertyname上触发PropertyChanged事件时,触发Left属性的绑定,将窗口移动到正确的X位置。 但是移动窗口的动作会触发“到源”,设置我的 viewModel 的 Top 属性。 EDIT : 没有“设置”完成,但是 Y 绑定没有被处理。

高度和宽度属性的行为相同。

这是一个显示我的问题的小应用程序。

这是模型:

 public class Model : INotifyPropertyChanged
    
        public event PropertyChangedEventHandler PropertyChanged;
        public Position SelectedPos  get; set; 
        public Position Pos1  get; set; 
        public Position Pos2  get; set; 

    public Model( int x, int y, int x2, int y2 )
    
        Pos1 = new Position( x, y );
        Pos2 = new Position( x2, y2 );
        SelectedPos = Pos1;
    

    public void Toggle()
    
        SelectedPos = Pos2;

        if( PropertyChanged != null )
        
            var e = new PropertyChangedEventArgs( "SelectedPos" );
            PropertyChanged( this, e );
        
    


public class Position

    int _x;
    public int X
    
        get  return _x; 
        set  _x = value; 
    

    int _y;
    public int Y
    
        get  return _y; 
        set  _y = value; 
    

    public Position( int x, int y )
    
        X = x;
        Y = y;
    

这是视图:

<Window x:Class="WpfApplication1.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" 
        Left="Binding Mode=TwoWay, Path=SelectedPos.X"
        Top="Binding Mode=TwoWay, Path=SelectedPos.Y">
    <Grid>
        <Button Click="Button_Click">Change Position</Button>
    </Grid>
</Window>

最后是代码隐藏:

namespace WpfApplication1

    public partial class MainWindow : Window
    
        Model model;

        public MainWindow()
        
            InitializeComponent();
            model = new Model( 5, 5, 500, 500 );
            DataContext = model;
        

        private void Button_Click( object sender, RoutedEventArgs e )
        
            model.Toggle();
        
    

我想知道的是,是否有某种方法可以“冻结”绑定,以防止引擎设置我的 viewModel,直到它处理完我要求它执行的所有绑定。或者在短时间内将绑定从 twoWay 切换到 OneWay。

这里的小应用程序在使用 .NET framework 3.5 时行为正确,但没有 4.0。

我很惊讶我找不到任何人在同样的问题上挣扎,我做错了什么吗? 感谢您的回答,如果有不清楚的地方,请随时询问。

让-卢普·卡伦


我今天早上已经添加了日志(我应该在发布之前就这样做了..),就像你做的那样,你是对的,没有完成“设置”,但是 Y 绑定没有被处理。 当实际切换几次窗口位置时,这种行为更加奇怪。

我将测试您的解决方案,即使我希望避免使用后面的代码(我使用一些代码仅用于测试目的)。

感谢您如此迅速地回答,当我有时间找到无代码隐藏的解决方案时,我会回复您。 由于未设置模型,我可以在触发行为怪异的“位置”绑定之后立即使用 propertychanged 事件分别触发 X 和 Y 绑定。

再次感谢,我走错路了,你为我节省了大量时间。

【问题讨论】:

【参考方案1】:

我不确定我是否同意你的观点

但是移动窗口的动作会触发“到源”,设置我的 viewModel 的 Top 属性。

我已经运行了您的代码,当您单击“更改位置”按钮时,我可以确认窗口从 (5, 5) 移动到 (500, 5)。但是,我随后添加了另一个按钮,其Click 事件处理程序将窗口的LeftTop 值写入调试日志。我发现这报告说窗口显然在 (500, 500)。然后我将它拖了一小段距离,再次单击此按钮,然后被告知窗口位于 (498, 4)。

我认为绑定工作正常,但由于某种原因,当其LeftTop 属性都通过绑定快速连续更改时,Windows 不会移动窗口。我不确定为什么会这样;这可能是 .NET 4 中的一个错误,尤其是在 .NET 3.5 中运行时。

我发现如果我添加 Position 类型的依赖属性并将其直接绑定到 SelectedPos 而不是绑定窗口的 LeftTop 属性,则窗口的行为与我预期的一样到SelectedPos 内的各个 X 和 Y 坐标。当这个依赖属性改变时,我将窗口的LeftTop 值设置为Position 中的XY 值。

我添加的依赖属性和属性改变回调如下:

    public Position WindowPosition
    
        get  return (Position)GetValue(WindowPositionProperty); 
        set  SetValue(WindowPositionProperty, value); 
    

    public static readonly DependencyProperty WindowPositionProperty =
        DependencyProperty.Register("WindowPosition", typeof(Position), typeof(MainWindow), new PropertyMetadata(WindowPosition_Changed));

    private static void WindowPosition_Changed(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    
        var mainWindow = obj as MainWindow;
        mainWindow.Left = mainWindow.WindowPosition.X;
        mainWindow.Top = mainWindow.WindowPosition.Y;
    

我发现绑定必须在代码隐藏中进行。我将这一行添加到MainWindow 构造函数中:

        SetBinding(WindowPositionProperty, new Binding("SelectedPos"));

最后,我在主窗口中删除了LeftTop 上的绑定。

【讨论】:

以上是关于使用 .NET 4.0 对“链接”变量(顶部/左侧和高度/宽度)进行双向绑定的主要内容,如果未能解决你的问题,请参考以下文章

为多个变量创建和填充页面 Swift 4.0

Wordpress 类似于 ASP.NET MVC2/3 或 ASP.NET 4.0 中的动态永久链接

.NET 4.0 中的新“动态”变量类型是不是解决了 CLR 中的单/多方法分派问题?

从 .net 2.0 转换到 4.0 后对性能问题进行故障排除

使用 jQuery 动画 scrollTop 总是从顶部开始

.NET 4.0 中的自定义 MembershipProvider