【问题标题】:WPF Data binding: Data bind element location on screen to TextBlock textWPF 数据绑定:将屏幕上的元素位置数据绑定到 TextBlock 文本
【发布时间】:2010-12-23 14:14:35
【问题描述】:

这是我的 XAML:

<Window x:Class="Gui.Wpf.MoveElementWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:converters="clr-namespace:Gui.Wpf.Converters" 
    Title="Move the red element" Height="300" Width="500">

    <Window.Resources>    
        <!-- Converter for element location -->
        <converters:LocationConverter x:Key="LocationConverter" />
    </Window.Resources>

    <Grid>

        <Rectangle 
            Name="RedRectangle" 
            Width="150" 
            Height="80" 
            Stroke="Black" 
            Fill="Red" 
            MouseDown="RedRectangle_MouseDown" 
            MouseMove="RedRectangle_MouseMove" />

        <TextBlock 
            Name="StatusTextBlock" 
            HorizontalAlignment="Left" 
            VerticalAlignment="Bottom" />

    </Grid>

</Window>

我希望能够将屏幕上RedRectangle 的位置数据绑定到StatusTextBlockText 属性,即我希望StatusTextBlock 说:“红色矩形的位置是:12、18 “ 例如。

我为PointString 的转换创建了一个转换器:

[ValueConversion(typeof(Point), typeof(String))]
public class LocationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        Point location;
        string valueString;

        location = (Point)value;

        valueString = string.Format("Red rectangle's location is: {0}, {1}", 
                                     location.X, location.Y);

        return valueString;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

我不知道如何对矩形的位置进行数据绑定,因为它不是通过属性提供的,而是通过方法提供的:RedRectangle.PointToScreen(new Point(0,0));。请帮忙,谢谢。

【问题讨论】:

    标签: wpf data-binding binding


    【解决方案1】:

    问题是您的矩形位于错误类型的面板(或容器)内。您正在使用 Grid 将其子项排列到由许多行/列定义的单元格中。您需要一个允许您将位置指定为像素坐标的容器。为此,您需要一个 Canvas:

    <Canvas>
        <Rectangle 
            Name="RedRectangle" 
            Canvas.Left="{Binding Path=Text, ElementName=StatusTextBlock, Converter={StaticResource LocationConverterLeft}}"  
            Canvas.Top="{Binding Path=Text, ElementName=StatusTextBlock, Converter={StaticResource LocationConverterTop}}"
            Width="150" 
            Height="80" 
            Stroke="Black" 
            Fill="Red" 
            MouseDown="RedRectangle_MouseDown" 
            MouseMove="RedRectangle_MouseMove" />
    </Canvas>
    

    注意,您需要转换器,一个用于顶部,另一个用于左侧属性。

    【讨论】:

    • 注意:如果你想要双向绑定,即你打算更新你的矩形顶部/左侧属性,并期望你的 TextBox 文本更新,你将需要一个 MultiBinding。
    • 我制定了一个类似的解决方案 :) 但在再次阅读问题后,我认为 OP 只想在 TextBlock 中显示 Rectangle 的位置,而不是相反。但我可能是错的..
    • @Meleak 你说得对,我只需要在移动矩形时知道它的 X、Y。
    • 您的代码将如何更新TextBlockText 属性?我需要在TextBlock 而不是Rectangle 中设置绑定,或者我没有看到什么?至于这两个转换器,我不敢苟同,因为我应该在StatusTextBlock.Text 上只有一个绑定,并应用一个转换器。
    • 好的,你以前用过多重绑定吗?您可以在绑定矩形的 Canvas.Top 和 Canvas.Left 属性的 StatusTextBlock.Text 属性上提供多重绑定。
    【解决方案2】:

    你可以传入元素本身,然后调用方法:

    public class LocationConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, 
            object parameter, CultureInfo culture)
        {
            var uiElement = value as UIElement;
            if (uiElement == null)
                return "";
    
            var location = uiElement.PointToScreen(0,0);
    
            valueString = string.Format("Red rectangle's location is: {0}, {1}", 
                                         location.X, location.Y);
    
            return valueString;
        }
    
        public object ConvertBack(object value, Type targetType, 
            object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    

    绑定将是:

    <TextBlock Text={Binding ElementName=RedRectangle}" Name="StatusTextBlock" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
    

    没试过,应该可以的。

    【讨论】:

    • 虽然矩形的位置发生变化,但绑定可能不会触发
    猜你喜欢
    • 2011-01-01
    • 2013-01-15
    • 2019-03-15
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 2018-05-23
    相关资源
    最近更新 更多