2016-07-14 3 views
0

MVVM 패턴과 함께 WPF를 사용하고 있습니다.수동으로 창 위치 설정 wpf mvvm

새 창 위치 (왼쪽, 위쪽, 너비, 높이)를 동적으로 설정하려면 다른 컨트롤의 좌표를 가져 와서 기본 창에있는 테두리가 주 창이라고 말합니다. 나는 주 창에서 다음 코드를 사용하고 있습니다 :

<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 버튼을 클릭하여 새 창을 말을 시작합니다. 새 창을 시작하는 것은 문제가되지 않지만이 창을 기본 창에서 테두리와 같은 위치로 시작하려고합니다. 새 창은 기본 창의 테두리에 정확히 맞아야합니다.

+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(); 
    } 

수정 # 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

을 삭제하는 것은 MVVM에서 가능합니까? – user2749679

+0

@ user2749679 업데이트 된 답변보기 – AnjumSKhan