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.
精彩评论