2016-07-14 10 views
0

MVVMパターンのWPFを使用しています。ウィンドウの位置を手動で設定するwpf mvvm

新しいウィンドウの位置(左、上、幅、高さ)を動的に設定したいのは、他のコントロールの座標を取得することです。ベースウィンドウにあるBorderはメインウィンドウと言います。私は、メインウィンドウに次のコード使用しています :

<Window x:Class="WpfApplication3.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     mc:Ignorable="d" 
     xmlns:local="clr-namespace:WpfApplication3" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <local:MainVM/> 
    </Window.DataContext> 
    <DockPanel> 
     <StackPanel DockPanel.Dock="Left" HorizontalAlignment="Left"> 
      <Button Content="OK" Width="100"></Button> 
     </StackPanel> 
     <Border DockPanel.Dock="Top" BorderBrush="Green" Background="Black" BorderThickness="2" > 
     </Border> 
    </DockPanel> 
</Window> 

を今私は、新しいウィンドウを起動するには、[OK]ボタンをクリックして新しいウィンドウを言います。 新しいウィンドウを起動することは問題ではありませんが、私はこのウィンドウをBorder on Main Windowのような同じ位置に起動したいと思います。 新しいウィンドウは、メインウィンドウの枠内に正確に収まる必要があります。

+0

は重複ではありません。 – Kcvin

+0

ウィンドウの位置付けは、ビューのみに関連する問題です。そのため、ViewModelのプロパティのTop、Left、Width、Heightをバインドしようとする必要はありません。代わりに、コードビハインドで行います。 – Kcvin

+0

私のコメント – Dheeraj

答えて

1

以下のコードは、あなたの問題を解決:

XAML:

<Grid> 
    <Border x:Name="Brd" Margin="50,46,0,0" BorderBrush="#FFB82E2E" Background="#FFC7DC42" BorderThickness="5" CornerRadius="5"> 
     <Label Content="a label"/> 
    </Border> 
    <Button Content="Button" HorizontalAlignment="Left" Margin="32,15,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/> 
</Grid> 

コード:

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Window w = new Window(); 
     w.Width = Brd.ActualWidth; 
     w.Height = Brd.ActualHeight; 

     Point pt = Brd.PointToScreen(new Point(0, 0)); 
     PresentationSource source = PresentationSource.FromVisual(this); 
     System.Windows.Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(pt); 

     w.Top = targetPoints.Y; 
     w.Left = targetPoints.X; 
     w.Show(); 
    } 

EDIT#1(ユーザの要求の後)

純粋MVVMのために、あなたは添付された動作を記述する必要があります。私はすべてMainWindow名前空間の下に置いています。

使用法:

<Window.Resources> 
    <Window x:Key="NewWindowKey"/> 
</Window.Resources> 
<Grid> 
    <Border x:Name="Brd" Margin="50,46,0,0" BorderBrush="#FFB82E2E" Background="#FFC7DC42" BorderThickness="5" CornerRadius="5">    
     <Label Content="a label"/> 
    </Border> 
    <Button Content="Button" HorizontalAlignment="Left" Margin="32,15,0,0" VerticalAlignment="Top" Width="75"> 
     <local:ApplicationBehaviors.WindowPlacementBehavior> 
      <local:NewWindowToShowParameters NewWindow="{StaticResource NewWindowKey}" TargetVisualName="Brd"/> 
     </local:ApplicationBehaviors.WindowPlacementBehavior> 
    </Button> 
</Grid> 

コード:この@Dheeraj

public static class ApplicationBehaviors 
{ 
    public static NewWindowToShowParameters GetWindowPlacementBehavior(DependencyObject obj) 
    { 
     return (NewWindowToShowParameters)obj.GetValue(WindowPlacementBehaviorProperty); 
    } 

    public static void SetWindowPlacementBehavior(DependencyObject obj, NewWindowToShowParameters value) 
    { 
     obj.SetValue(WindowPlacementBehaviorProperty, value); 
    } 

    // Using a DependencyProperty as the backing store for WindowPlacement. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty WindowPlacementBehaviorProperty = 
     DependencyProperty.RegisterAttached("WindowPlacementBehavior", typeof(NewWindowToShowParameters), typeof(ApplicationBehaviors), new PropertyMetadata(null, new PropertyChangedCallback(WindowPlacementChanged))); 

    private static void WindowPlacementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Button ctrl = d as Button; 
     ctrl.Click += ((s, args) => 
     { 
      DependencyObject parent = VisualTreeHelper.GetParent(ctrl); 
      while ((parent as Window) == null) 
       parent = VisualTreeHelper.GetParent(parent); 

      Window rootWindow = (Window)parent; 

      NewWindowToShowParameters newWindowParams = ((NewWindowToShowParameters)e.NewValue); 
      Window newWin = newWindowParams.NewWindow; 
      Border b = (Border) rootWindow.FindName(newWindowParams.TargetVisualName); 

      newWin.Width = b.ActualWidth; 
      newWin.Height = b.ActualHeight; 

      Point pt = b.PointToScreen(new Point(0, 0)); 
      PresentationSource source = PresentationSource.FromVisual(rootWindow); 
      System.Windows.Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(pt); 

      newWin.Top = targetPoints.Y; 
      newWin.Left = targetPoints.X; 
      newWin.Show(); 
     }); 
    }   
} 

public class NewWindowToShowParameters 
{ 
    public Window NewWindow { get; set; } 
    public string TargetVisualName { get; set; } 
} 
+0

を削除することは可能ですか? – user2749679

+0

@ user2749679更新された回答を見る – AnjumSKhan

関連する問題