开发者

WPF Data binding: Data bind element location on screen to TextBlock text

Here's my 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>

I want to be able to data bind RedRectangle's location on screen to the StatusTextBlock's Text property, i.e. I want the StatusTextBlock to say: "Red rectangle's location is: 12, 18开发者_高级运维" for example.

I have created a converter for the Point to String conversion:

[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();
    }
}

What I don't know is how to data bind the rectangle's location, as it is not provided through a property, but through a method instead: RedRectangle.PointToScreen(new Point(0,0));. Please help, thanks.


The problem is your rectangle is sitting within the wrong type of panel (or container). You are using a Grid whcih arranges its children into cells defined by a number of rows / columns. You need a container that allows you to specify the location as pixel coordinates. For this you need a 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>

Note, you would need to converters, one for the top and the other for the left property.


You could pass in the element itself and then call the method:

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();
    }
}

And the binding would be:

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

Haven't tried it, but that should work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜