我希望问这个问题不会太傻,但我正在尝试设计一个WPF图形查看器,作为这个框架的新手;虽然我已经想出了一些解决问题的方法,但我最自豪的一个……在应该工作的地方却不起作用。我试图做的是在使用Dijkstra算法和一些数学计算后,在ItemsControl上放置一个节点。问题在于,当使用普通的X和Y绑定移动时,移动的是TextBlock与边框的左上角,但我想要操作的是它们的中心位置。因此,我的节点最终会从我指定的点向下和向右粘在一起,而不是居中。
我最终选择了使用NodeViewModel的X / Y属性和Grid的ActualWidth / Height进行Multibinding。结果发生的事情是所有我的节点都被放置在(0,0)处 strong>!我甚至调试了代码并查看了转换器,但返回值似乎是正确的。我甚至尝试了一些随机的东西,比如绑定到其他属性等。
我完全困惑了。
那么一个问题是-多绑定是否能够按照这种方式工作?或者我犯了一些愚蠢的错误?我会在XAML代码下面发布我的转换器。在XAML切出的部分是工具提示和嵌入的ItemsControl,但切出这些部分不会改变任何东西(除了改善代码的清晰度)。转换器中的转型是因为直接转换为float对我没有用(但这是无关紧要的-它可以按照它的方式工作,即使它不是非常美丽)。
另一个问题是 - 我能以任何更简单的方式完成吗?比如直接操作TextBlock的中心?
XAML:
<Grid>
<ItemsControl ItemsSource="{Binding Source={StaticResource Nodes}, Path=Nodes}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vievModels:NodeViewModel">
<Grid>
<Grid x:Name="nodeGrid">
<Grid.RenderTransform>
<TranslateTransform>
<TranslateTransform.X>
<MultiBinding Converter="{StaticResource PositionConverter}">
<Binding Path="Position.X"/>
<Binding ElementName="nodeGrid" Path="ActualWidth"/>
</MultiBinding>
</TranslateTransform.X>
<TranslateTransform.Y>
<MultiBinding Converter="{StaticResource PositionConverter}">
<Binding Path="Position.Y"/>
<Binding ElementName="nodeGrid" Path="ActualHeight"/>
</MultiBinding>
</TranslateTransform.Y>
</TranslateTransform>
</Grid.RenderTransform>
<Border BorderBrush="Black" BorderThickness="2" CornerRadius="7">
<Border.Background>
<SolidColorBrush Color="{Binding Color}" Opacity="0.5"/>
</Border.Background>
<TextBlock x:Name="Label" Margin="5,5,5,5" MaxWidth="160" TextAlignment="Center" TextWrapping="Wrap" FontFamily="Lucida Console" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Path=Label}"/>
</Border>
...
</Grid>
...
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="Transparent"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
C#:
public class PositionConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
float point = float.Parse(values[0].ToString());
float size = float.Parse(values[1].ToString());
return point - size / 2;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Cheers, Michael