質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

1055閲覧

マウスに追従して図形が動くWPFアプリケーションを作りたい

waribashi

総合スコア30

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2023/01/10 07:42

実現したいこと

  • マウスに追従して図形が動くWPFアプリケーションを作りたい
  • 上の目的が達成できて,WPFアプリケーションであれば,使うツールは何でもいい
  • WPF初心者です

困っていること

WPFで図形をマウスに追従させるのコードビハインドを汚す場合をほぼ丸写ししたのですが,マウスをウィンドウ上で動かすと,VM.X.Value = mousepos.X;の行で以下のようなエラーメッセージが出てきます.

System.NullReferenceException: 'Object reference not set to an instance of an object.' projectorButtonWpf.MainWindow.VM.get が null を返しました。

コード

xaml

1<Window x:Name="Window" x:Class="projectorButtonWpf.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:projectorButtonWpf" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="600" Width="600" MouseMove="Window_MouseMove"> 9 10 <Grid> 11 <Canvas MouseMove="MouseMoveHandler" 12 Background="#00FFFACD"> 13 <Rectangle Stroke="Green" 14 StrokeThickness="5" 15 Width="50" 16 Height="50" 17 HorizontalAlignment="Left" 18 VerticalAlignment="Top"> 19 <Rectangle.RenderTransform> 20 <TransformGroup> 21 <TranslateTransform 22 X="{Binding X.Value}" 23 Y="{Binding Y.Value}"/> 24 </TransformGroup> 25 </Rectangle.RenderTransform> 26 </Rectangle> 27 </Canvas> 28 </Grid> 29</Window>

cs

1using System.Windows.Input; 2using Reactive.Bindings; 3using System.Diagnostics; 4 5namespace projectorButtonWpf 6{ 7 public partial class MainWindow : System.Windows.Window 8 { 9 public class MainWindowViewModel 10 { 11 public ReactivePropertySlim<double> X { get; } = new ReactivePropertySlim<double>(); 12 public ReactivePropertySlim<double> Y { get; } = new ReactivePropertySlim<double>(); 13 } 14 15 public MainWindow() 16 { 17 InitializeComponent(); 18 } 19 private MainWindowViewModel VM => (MainWindowViewModel)DataContext; 20 21 private void Window_MouseMove(object sender, MouseEventArgs e) 22 { 23 var mousepos = e.GetPosition(this); 24 VM.X.Value = mousepos.X; //この行でエラーが出る 25 VM.Y.Value = mousepos.Y; 26 } 27 } 28} 29

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

コードビハインドでいいなら、ViewModelもバインドも必要ありません。
x:Nameをつけて直接変更するだけです。

xml

1<Window 2 x:Class="Qu3i0m8mi71wgt7.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450" 7 MouseMove="Window_MouseMove"> 8 <UniformGrid> 9 10 <Grid x:Name="grid" Margin="20"> 11 <Rectangle 12 Width="50" 13 Height="50" 14 HorizontalAlignment="Left" 15 VerticalAlignment="Top" 16 Stroke="Green" 17 StrokeThickness="5"> 18 <Rectangle.RenderTransform> 19 <TranslateTransform x:Name="translateTransform" /> 20 </Rectangle.RenderTransform> 21 </Rectangle> 22 </Grid> 23 24 <Canvas x:Name="canvas" Margin="20"> 25 <Rectangle 26 x:Name="rectangle" 27 Width="80" 28 Height="80" 29 Stroke="Blue" 30 StrokeThickness="5" /> 31 </Canvas> 32 </UniformGrid> 33</Window>

cs

1using System; 2using System.Windows; 3using System.Windows.Controls; 4using System.Windows.Input; 5using System.Windows.Media; 6 7namespace Qu3i0m8mi71wgt7 8{ 9 public partial class MainWindow : Window 10 { 11 public MainWindow() 12 { 13 InitializeComponent(); 14 15 // こういう手もある 16 //CompositionTarget.Rendering += CompositionTarget_Rendering; 17 } 18 19 private void Window_MouseMove(object sender, MouseEventArgs e) 20 { 21 // コンテナ(grid)にMarginがあったりすると、GetPosition(this)ではズレる。 22 var point = e.GetPosition(grid); 23 translateTransform.X = point.X; 24 translateTransform.Y = point.Y; 25 26 point = e.GetPosition(canvas); 27 Canvas.SetLeft(rectangle, point.X); 28 Canvas.SetTop(rectangle, point.Y); 29 } 30 31 //private void CompositionTarget_Rendering(object sender, EventArgs e) 32 //{ 33 // var point = Mouse.GetPosition(grid); 34 // translateTransform.X = point.X; 35 // translateTransform.Y = point.Y; 36 37 // point = Mouse.GetPosition(canvas); 38 // Canvas.SetLeft(rectangle, point.X); 39 // Canvas.SetTop(rectangle, point.Y); 40 //} 41 } 42}

投稿2023/01/10 10:15

TN8001

総合スコア9321

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2023/01/10 10:15

解決されたようなので蛇足ですが。
guest

0

自己解決

以下のステップで

ViewModelフォルダ,MainViewModel.csを追加
イメージ説明

MainViewModel.csは以下のように記述

cs

1using Reactive.Bindings; 2 3namespace projectorButtonWpf.ViewModel 4{ 5 class MainViewModel 6 { 7 public ReactivePropertySlim<double> X { get; } = new ReactivePropertySlim<double>(); 8 public ReactivePropertySlim<double> Y { get; } = new ReactivePropertySlim<double>(); 9 10 } 11}

③XAMLを以下のように変更(7,10~12行目部分を追加)

XAML

1<Window x:Name="Window" x:Class="projectorButtonWpf.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:projectorButtonWpf" 7 xmlns:vm="clr-namespace:projectorButtonWpf.ViewModel" 8 mc:Ignorable="d" 9 Title="MainWindow" Height="600" Width="600" MouseMove="Window_MouseMove"> 10 <Window.DataContext> 11 <vm:MainViewModel/> 12 </Window.DataContext> 13 <Grid> 14 <Rectangle Stroke="Green" 15 StrokeThickness="5" 16 Width="50" 17 Height="50" 18 HorizontalAlignment="Left" 19 VerticalAlignment="Top"> 20 <Rectangle.RenderTransform> 21 <TransformGroup> 22 <TranslateTransform 23 X="{Binding X.Value}" 24 Y="{Binding Y.Value}"/> 25 </TransformGroup> 26 </Rectangle.RenderTransform> 27 </Rectangle> 28 </Grid> 29</Window>

MainWindow.xaml.csを以下のように変更
以下削除

cs

1 public class MainWindowViewModel 2 { 3 public ReactivePropertySlim<double> X { get; } = new ReactivePropertySlim<double>(); 4 public ReactivePropertySlim<double> Y { get; } = new ReactivePropertySlim<double>(); 5 }

private MainWindowViewModel VM => (MainWindowViewModel)DataContext;

private MainViewModel vm => (MainViewModel)DataContext;
に変更

ーーーーー
以下MainWindow.xaml.cs全文

cs

1using System.Windows.Input; 2using Reactive.Bindings; 3using System.Diagnostics; 4using projectorButtonWpf.ViewModel; 5 6namespace projectorButtonWpf 7{ 8 public partial class MainWindow : System.Windows.Window 9 { 10 public MainWindow() 11 { 12 InitializeComponent(); 13 } 14 private MainViewModel vm => (MainViewModel)DataContext; 15 16 private void Window_MouseMove(object sender, MouseEventArgs e) 17 { 18 var mousepos = e.GetPosition(this); 19 vm.X.Value = mousepos.X; 20 vm.Y.Value = mousepos.Y; 21 } 22 } 23}

参考:https://www.curict.com/item/51/51fd5f6.html

投稿2023/01/10 08:11

waribashi

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問