【问题标题】:WPF Moving object by Grid.Row?WPF 通过 Grid.Row 移动对象?
【发布时间】:2018-07-19 09:07:21
【问题描述】:

我有一个问题,如何在 WPF 应用程序中按行移动对象?我的 Xaml 如下所示:

 <Grid>
    <Grid.ColumnDefinitions>
        <Some columns here!/>
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <Some Rows here!/>
    </Grid.RowDefinitions>

        <Button x:Name="Button1"               
            Grid.Row="1" Grid.Column="4"
            Width="50" Height="50" 
            Content="Button1" 
            Foreground="White" 
            BorderThickness="0"  
            Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" 
            BorderBrush="{x:Null}" 
            Background="#FF085078"/>

        <Button x:Name="Button2"               
            Grid.Row="2" Grid.Column="4"
            Content="Button2" 
            Foreground="White" 
            BorderThickness="0"  
            Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" 
            BorderBrush="{x:Null}" 
            Background="#FF085078"/>

        <ContentControl Grid.Row="1" Grid.Column="2" Grid.RowSpan="2" Grid.ColumnSpan="3"
                    x:Name="ActiveItem"/>

我想要做的是,当我在内容控件中显示另一个窗口时,我想从内容控件的第二个视图下移动“Button2”。如何在内容控制下移动项目,当我关闭第二个视图时,项目会回到它们的主要位置?如何绑定 Grid.Row 以做我想做的事?如果有帮助,我正在使用 Caliburn.Micro 框架>

感谢您的建议!

【问题讨论】:

  • Grid.SetRow(Button2, 3); 不是你想要的?
  • 您还可以将 Grid.Row 绑定到可绑定属性
  • @Clemens 是的,这正是我想要的!
  • @Bijan 你能解释一下如何正确绑定 SetRow 吗?我打赌我需要创建移动对象的方法,然后在显示 ContentControl 的方法中调用该方法来移动对象
  • 如果您想在 ContentControl 的 Content 为非 null 时移动 Button,您还可以使用带有 DataTrigger 的 Button Style 作为纯 XAML 解决方案。

标签: c# wpf xaml mvvm caliburn.micro


【解决方案1】:

您可以声明一个按钮样式,根据 ContentControl 的 Content 是否为空来设置 Grid.Row 属性值:

<Button Content="Button2" Grid.Column="4">
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="Grid.Row" Value="3"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Content, ElementName=ActiveItem}"
                             Value="{x:Null}">
                    <Setter Property="Grid.Row" Value="2"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

如果已经有 Style 分配了

<Button Style="{StaticResource X}" .../>

删除它并写下:

<Button ...>
    <Button.Style>
        <Style TargetType="Button" BasedOn="{StaticResource X}">
            ...
        </Style>
    </Button.Style>
</Button>

【讨论】:

  • 这看起来很容易使用,谢谢!但是当 VS 对我大喊大叫时该怎么办,“样式”属性设置了不止一次,我无法进入 正文?与“内容”值相同的历史记录。我在主帖中更新了我的按钮模式
  • 一个属性只能设置一次。通过属性标签&lt;Control Prop="X" 或作为自己的节点&lt;Control.Prop&gt;。删除不需要的那个。 @metadon789
  • 我还有一个问题,如果我想拥有多个像上面这样的数据触发器怎么办? @克莱门斯
【解决方案2】:

首先将每个Grid.Row 绑定到一个可绑定属性。

<Grid>
    <Grid.ColumnDefinitions>
        <Some columns here!/>
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <Some Rows here!/>
    </Grid.RowDefinitions>

    <Button x:Name="Button1"               
        Grid.Row="{Binding Button1Row}" Grid.Column="4"
        Width="50" Height="50" 
        Content="Button1" />

    <Button x:Name="Button2"               
        Grid.Row="{Binding Button2Row}" Grid.Column="4"
        Width="50" Height="50" 
        Content="Button2"/>

    <ContentControl Grid.Row="{Binding ContentControlRow}" Grid.Column="2" Grid.RowSpan="2" Grid.ColumnSpan="3"
                x:Name="ActiveItem"/>
</Grid>

现在在您的 DataContext 绑定对象中,您需要定义这些可绑定属性。

请注意,在 MVVM 中,行号可能被视为 view 事物而不是 ViewModel 事物。所以首先你需要决定你想走哪条路。

  1. 您可以在ViewModel中添加这些可绑定属性,并通过命令进行修改。

  2. 您可以将它们直接添加到 view 的代码隐藏(MyWindow.xaml.cs 或 MyUserControl.xaml.cs)并通过 事件处理程序修改它们强>.

第二种情况:

  1. 您可能会忘记绑定,只需按照 Clemens 的建议使用 Grid.SetRow(Button2, 3);

  2. 或者您可以通过这些修改使用绑定:

    • 将承载网格的用户控件(或窗口)的x:Name 设置为例如MyUserControlRoot.
    • ElementName 添加到绑定中。 例如Grid.Row="{Binding ElementName=MyUserControlRoot, Path=Button1Row}"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-28
    • 2017-05-01
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    相关资源
    最近更新 更多