简体   繁体   English

如何使用XAML绑定到WPF中的父位置更改,并且后面没有代码

[英]How to bind to parent position changes in WPF using XAML and no code behind

I have a visio-like interfact but have actual model data behind some of the elements. 我有一个类似visio的interfact,但在一些元素后面有实际的模型数据。 The elements can be moved by the user. 用户可以移动元素。

I use a contentcontrol on a canvas whereby the viewmodels of the elements are places in the content which can then be displayed differently depending on their type but using the same contentcontrol. 我在画布上使用contentcontrol,其中元素的视图模型是内容中的位置,然后可以根据其类型显示不同但使用相同的contentcontrol。 It is simple to bind the view to the different properties in the viewmodel. 将视图绑定到viewmodel中的不同属性很简单。 However, I have to save the position in the model, and I cannot find a binding solution. 但是,我必须保存模型中的位置,我找不到绑定解决方案。

1) The Application.Save Command is handled in the main view model, so I do not have access to the view there. 1)Application.Save命令在主视图模型中处理,因此我无法访问该视图。 That means I must save the postion data when the elements are moved, or is there a better approach? 这意味着我必须在元素移动时保存位置数据,还是有更好的方法?

2) Assuming that I am right with 1), I am looking to avoid code behind, ie I do not want the contentcontrol to deal with the elements that they have in their content. 2)假设我对1)是正确的,我希望避免代码落后,即我不希望contentcontrol处理它们在其内容中的元素。 However, so far the code behind version is all I could come up with: 但是,到目前为止,版本背后的代码是我能想到的:

My code behind solution so far: 到目前为止我的解决方案代码:

All model elements implement an interface: 所有模型元素都实现一个接口:

public interface IViewElement
{
    String Position { get; set; }
}

And in the contentcontrol: 并在contentcontrol中:

 void ContentControl_LayoutUpdated(object sender, EventArgs e)
    {
        IViewElement content = this.Content as IViewElement;
        content.Position = new Point(Diagram.GetLeft(this), Diagram.GetTop(this)).ToString();
    }

The XAML: XAML:

<Style TargetType="{x:Type diagram:Item}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type diagram:Item}">
                <Grid Canvas.Top="{Binding ElementName=PART_ContentPresenter, Path=Content.Position, Mode=TwoWay}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"
                    ContextMenu="{x:Null}">
                    <!-- PART_ContentPresenter -->
                    <ContentPresenter x:Name="PART_ContentPresenter"
                        Content="{TemplateBinding Content}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

<DataTemplate DataType="{x:Type local:ViewModel}">
<StackPanel>
    ...
</StackPanel>

只需封装您在行为中使用的代码隐藏

Why are you using a string to store the position? 你为什么用字符串存储位置? Use either a Point or two decimal values, and then bind your ContentControl's Canvas.Top and Canvas.Left position to these values using two-way binding. 使用Point或两个十进制值,然后使用双向绑定将ContentControl的Canvas.TopCanvas.Left位置绑定到这些值。

It will automatically update the model when the Top and Left positions change. 当顶部和左侧位置发生变化时,它会自动更新模型。

Edit: Here's an example: 编辑:这是一个例子:

<ContentControl Canvas.Top="{Binding ContentModel.Top, Mode=TwoWay}"
                Canvas.Left="{Binding ContentModel.Left, Mode=TwoWay}"
                Content="{Binding ContentModel}" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM