WinUI3 メモ レイアウト - DrumMidiEditor/DrumMidiEditorApp GitHub Wiki
コードから直接更新
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition x:Name="_PlayerRightColumn"
Width="{x:Bind ConfigPlayer.PlayerLayoutSize, Mode=TwoWay}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition x:Name="_PlayerBottomRow"
Height="{x:Bind ConfigPlayer.PlayerLayoutSize, Mode=TwoWay}" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:PageMenuBar x:Name="_PageMenuBar"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2" />
<local:PageNavigation x:Name="_PageNavigation"
Grid.Row="1"
Grid.RowSpan="1"
Grid.Column="0"
Grid.ColumnSpan="2" />
<psurface:PagePlayer x:Name="_PagePlayer"
Grid.Row="2"
Grid.RowSpan="1"
Grid.Column="0"
Grid.ColumnSpan="2" />
<local:PageStatusBar x:Name="_PageStatusBar"
Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="2" />
</Grid>
public void UpdateGridLayout()
{
try
{
int row;
int rowspan;
int col;
int colspan;
switch ( ConfigPlayer.PlayerLayoutModeSelect )
{
case ConfigPlayer.PlayerLayoutMode.Right:
row = 1;
rowspan = 2;
col = 1;
colspan = 1;
break;
case ConfigPlayer.PlayerLayoutMode.Bottom:
row = 2;
rowspan = 1;
col = 0;
colspan = 2;
break;
default:
return;
}
// x:Bind経由では更新できなかったので直接設定
Grid.SetRowSpan ( _PageNavigation, rowspan );
Grid.SetColumnSpan ( _PageNavigation, colspan );
Grid.SetRow ( _PagePlayer, row );
Grid.SetRowSpan ( _PagePlayer, rowspan );
Grid.SetColumn ( _PagePlayer, col );
Grid.SetColumnSpan ( _PagePlayer, colspan );
}
catch ( Exception e )
{
Log.Error( $"{Log.GetThisMethodName}:{e.Message}" );
}
}
下にプレイヤー表示
右にプレイヤー表示
現状、別ウィンドウを作成できないので、RelativePanel を使用して
画面内で移動できるパネルを作成する。

- メインページ側で、RelativePanel を使用して、レイアウトを設定
<RelativePanel>
<local1:PageMenuBar x:Name="_PageMenuBar"
RelativePanel.AlignTopWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True" />
<local3:PageNavigation x:Name="_PageNavigation"
RelativePanel.Below="_PageMenuBar"
RelativePanel.Above="_PageStatusBar"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True" />
<local2:PageStatusBar x:Name="_PageStatusBar"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True" />
<local4:PagePlayer x:Name="_PagePlayer"
RelativePanel.AlignTopWithPanel="True"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
Visibility="{x:Bind ConfigPlayer.DisplayPlayerVisibility, Mode=OneWay}" />
</RelativePanel>
RelativePanelの指定方法
属性名 | 設定内容 |
---|---|
Align~WithPanel | Trueで、グリッド内の左右上下に引っ付ける |
Align~With | 入力したアイテム名の左右上下に配置 |
Above | 入力したアイテム名の上に配置 |
Below | 入力したアイテム名の下に配置 |
LeftOf | 入力したアイテム名の左に配置 |
RightOf | 入力したアイテム名の右に配置 |
- 画面内で移動できるパネルの定義
<Page
PointerPressed="Page_PointerPressed"
PointerMoved="Page_PointerMoved"
PointerReleased="Page_PointerReleased"
PointerCaptureLost="Page_PointerReleased"
PointerCanceled="Page_PointerReleased"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="#00000000">
</Page>
/// <summary>
/// 表示位置調整用マージン
/// </summary>
private Thickness _PageMargin = new();
/// <summary>
/// マウスアクション
/// </summary>
private enum EActionState : int
{
None = 0,
PlayerMove,
PlayerOff,
}
/// <summary>
/// マウスアクション状態
/// </summary>
private EActionState _ActionState = EActionState.None;
/// <summary>
/// ページ移動前の位置
/// </summary>
private Point _BeforePos = new();
/// <summary>
/// マウスダウン処理
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void Page_PointerPressed( object sender, PointerRoutedEventArgs args )
{
if ( _ActionState != EActionState.None )
{
return;
}
// ページ内ではなく、メインページ基準でのマウスの入力情報を取得する
var p = args.GetCurrentPoint( ControlAccess.PageEditerMain );
// var p = args.GetCurrentPoint( sender as FrameworkElement );
if ( p.Properties.IsLeftButtonPressed )
{
// フォーム移動
_BeforePos = p.Position;
_ActionState = EActionState.PlayerMove;
}
else if ( p.Properties.IsRightButtonPressed )
{
// 非表示
DrawSet.DisplayPlayer = false;
Config.EventUpdatePlayerDisplay();
_ActionState = EActionState.None;
}
}
/// <summary>
/// マウス移動処理
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void Page_PointerMoved( object sender, PointerRoutedEventArgs args )
{
if ( _ActionState == EActionState.None )
{
return;
}
// ページ内ではなく、メインページ基準でのマウスの入力情報を取得する
var p = args.GetCurrentPoint( ControlAccess.PageEditerMain );
// var p = args.GetCurrentPoint( sender as FrameworkElement );
switch ( _ActionState )
{
case EActionState.PlayerMove:
SetPagePosition( p.Position );
break;
}
}
/// <summary>
/// マウスアップ処理
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void Page_PointerReleased( object sender, PointerRoutedEventArgs args )
{
if ( _ActionState == EActionState.None )
{
return;
}
// ページ内ではなく、メインページ基準でのマウスの入力情報を取得する
var p = args.GetCurrentPoint( ControlAccess.PageEditerMain );
// var p = args.GetCurrentPoint( sender as FrameworkElement );
switch ( _ActionState )
{
case EActionState.PlayerMove:
SetPagePosition( p.Position );
break;
}
_ActionState = EActionState.None;
}
/// <summary>
/// プレイヤー表示位置設定
/// </summary>
/// <param name="aMousePoint"></param>
private void SetPagePosition( Point aMousePoint )
{
_PageMargin.Left += aMousePoint.X - _BeforePos.X;
_PageMargin.Top += aMousePoint.Y - _BeforePos.Y;
_BeforePos = aMousePoint;
Margin = _PageMargin;
}
テーブル表示の1つ
<VariableSizedWrapGrid
Orientation="Horizontal"
MaximumRowsOrColumns="2"
Width="200"
HorizontalAlignment="Left"
ItemHeight="64"
ItemWidth="100" >
<NumberBox />
<Button />
</VariableSizedWrapGrid>

- アイテムサイズは固定の為、最小単位のアイテムサイズを決め
各要素にセル結合数を指定してサイズを調整する。
VariableSizedWrapGrid.ColumnSpan="2"
VariableSizedWrapGrid.RowSpan="2"
- Width または Height を指定していない場合
サイズを小さくしたときに各要素がラップされる。

