c# - 用户自定义表单,wpf 绑定控件位置
问题描述
我试图让用户设计自己的表单并将控件位置保存到数据库中。现在,我能够允许用户生成新控件并在表单中移动它们。我不知道如何让控件的位置到我的 Datacontext。我只能绑定宽度等...
我希望我可以将 canvas.left 和 canvas.top 绑定到 datacontext,但是这些在 renderTransform 上没有更新。
有什么想法吗?谢谢你的帮助。
这是用于移动控件的表单返回代码:
private Control _currentlyDragged;
private Point _currentlyDraggedMouseOffset;
private void Window_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (_currentlyDragged != null)
{
var mousePos = e.GetPosition(this);
var futurePos = e.GetPosition(BuildCanvas);
if (futurePos.X <= 0 || futurePos.Y <= 0 || futurePos.Y >= BuildCanvas.ActualHeight || futurePos.X >= BuildCanvas.ActualWidth)
return;
_currentlyDragged.RenderTransform = new TranslateTransform(mousePos.X - _currentlyDraggedMouseOffset.X, mousePos.Y - _currentlyDraggedMouseOffset.Y);
}
}
private void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_currentlyDragged != null)
_currentlyDragged = null;
ReleaseMouseCapture();
}
private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Point pt = e.GetPosition((UIElement)sender);
_hitResultsList.Clear();
VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(MyHitTestResult), new PointHitTestParameters(pt));
if (!_hitResultsList.Where(h => h is Border && ((Border)h).Name == "BuildCanvas").Any())
return;
if (_hitResultsList.Count > 0)
{
foreach (DependencyObject d in _hitResultsList)
{
var parent = VisualTreeHelper.GetParent(d);
if (parent != null && (parent is Label || parent is TextBox))
{
CaptureMouse();
_currentlyDragged = parent as Control;
if (_currentlyDragged.RenderTransform is TranslateTransform)
{
_currentlyDraggedMouseOffset.X = e.GetPosition(this).X - ((TranslateTransform)_currentlyDragged.RenderTransform).X;
_currentlyDraggedMouseOffset.Y = e.GetPosition(this).Y - ((TranslateTransform)_currentlyDragged.RenderTransform).Y;
}
else
{
_currentlyDraggedMouseOffset.X = pt.X;
_currentlyDraggedMouseOffset.Y = pt.Y;
}
return;
}
}
}
_currentlyDragged = null;
}
private HitTestResultBehavior MyHitTestResult(HitTestResult result)
{
_hitResultsList.Add(result.VisualHit);
return HitTestResultBehavior.Continue;
}
这是 ItemsControl:
<Border x:Name="BuildCanvas" Grid.Column="1" Grid.Row="0" Background="#fff4c9" CornerRadius="10">
<Grid>
<!-- Generated controls -->
<ItemsControl ItemsSource="{Binding TextBoxCollection}" Panel.ZIndex="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox HorizontalAlignment="Left" VerticalAlignment="Top" Padding="2" IsEnabled="False" Background="White"
Text="{Binding Name, Mode=OneWay}" Width="{Binding Width}">
</TextBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- -->
</Grid>
</Border>
解决方案
渲染转换是一个坏主意。每个文本框都在一个容器中。
您应该绑定 itemcontainer 的 Canvas.Top 和 Canvas.Left。就像是:
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding XviewModelProperty}" />
<Setter Property="Canvas.Top" Value="{Binding YviewModelProperty}" />
</Style>
</ItemsControl.ItemContainerStyle>
将文本框的数据上下文转换为任何视图模型类型并设置 XviewModelProperty 和 YviewModelProperty。
确保它们在设置时引发属性更改。
推荐阅读
- python - Dask Dataframes (Python):如何通过子文件运行计算?即如何利用底层文件结构?
- javascript - getuikit 模态根本不显示
- javascript - UnhandledPromiseRejectionWarning: DiscordAPIError: Invalid Form Body
- java - Gluon JavaFX maven nativerun 在加载 fxml 文件时出现错误
- apache-spark - 从文件列表而不是 Spark 中的 PATH 读取是否有效?
- owl - 删除具有 symmetricProperty 的语句时,GraphDB 的行为不一致
- javascript - 如何迭代地构建一个字符串
- excel - 如何检查任何工作表的 A 列中是否存在值,并在其为真的行中返回 B 列中的文本?
- javascript - 如何将 GET 请求与第三方小部件一起使用
- javascript - 如何更改表单中的多个输入