using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public sealed partial class MainWindow : Window
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 선형 플로우 레이아웃
/// </summary>
private LinedFlowLayout linedFlowLayout = null;
/// <summary>
/// 선형 플로우 레이아웃 데이터 템플리트
/// </summary>
private DataTemplate linedFlowLayoutDataTemplate = null;
/// <summary>
/// 스택 레이아웃
/// </summary>
private StackLayout stackLayout = null;
/// <summary>
/// 스택 레이아웃 데이터 템플리트
/// </summary>
private DataTemplate stackLayoutDataTemplate = null;
/// <summary>
/// 유니폼 그리드 레이아웃
/// </summary>
private UniformGridLayout uniformGridLayout = null;
/// <summary>
/// 유니폼 그리드 레이아웃 데이터 템플리트
/// </summary>
private DataTemplate uniformGridLayoutDataTemplate = null;
/// <summary>
/// 선형 플로우 레이아웃 라인 높이 비동기 적용 여부
/// </summary>
private bool applyLinedFlowLayoutLineHeightAsync = false;
/// <summary>
/// 선형 플로우 레이아웃 옵션 비동기 적용 여부
/// </summary>
private bool applyLinedFlowLayoutOptionsAsync = false;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
this.border.Loaded += border_Loaded;
this.linedFlowLayoutRadioButton.Checked += layoutRadioButton_Checked;
this.uniformGridLayoutRadioButton.Checked += layoutRadioButton_Checked;
this.stackLayoutRadioButton.Checked += layoutRadioButton_Checked;
this.lineSpacingNumberBox.ValueChanged += linedFlowLayoutSettingsNumberBox_ValueChanged;
this.minItemSpacingNumberBox.ValueChanged += linedFlowLayoutSettingsNumberBox_ValueChanged;
this.smallLineHeightRadioButton.Checked += lineHeightRadioButton_Checked;
this.largeLineHeightRadioButton.Checked += lineHeightRadioButton_Checked;
this.spacingNumberBox.ValueChanged += stackLayoutSettingsNumberBox_ValueChanged;
this.minColumnSpacingNumberBox.ValueChanged += uniformGridLayoutSettingsNumberBox_ValueChanged;
this.minRowSpacingNumberBox.ValueChanged += uniformGridLayoutSettingsNumberBox_ValueChanged;
this.mximumRowsOrColumnsNumberBox.ValueChanged += uniformGridLayoutSettingsNumberBox_ValueChanged;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 테두리 로드시 처리하기 - border_Loaded(sender, e)
/// <summary>
/// 테두리 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void border_Loaded(object sender, RoutedEventArgs e)
{
if(this.itemsView != null)
{
this.itemsView.ScrollView.ViewChanged += itemsViewScrollView_ViewChanged;
this.linedFlowLayout = this.itemsView.Layout as LinedFlowLayout;
this.linedFlowLayoutDataTemplate = this.itemsView.ItemTemplate as DataTemplate;
}
List<CustomDataObject> sourceList = CustomDataObject.GetCustomDataObjectList(includeAllItems: true);
ObservableCollection<CustomDataObject> sourceCollection = new ObservableCollection<CustomDataObject>(sourceList);
Task.Run
(
delegate ()
{
_ = DispatcherQueue.TryEnqueue
(
DispatcherQueuePriority.Low,
() =>
{
if(this.itemsView != null)
{
this.itemsView.ItemsSource = sourceCollection;
}
}
);
}
);
}
#endregion
#region 아이템 뷰 스크롤 뷰 뷰 변경시 처리하기 - itemsViewScrollView_ViewChanged(sender, e)
/// <summary>
/// 아이템 뷰 스크롤 뷰 뷰 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void itemsViewScrollView_ViewChanged(ScrollView sender, object e)
{
if(sender.VerticalOffset == 0 && (this.applyLinedFlowLayoutOptionsAsync || this.applyLinedFlowLayoutLineHeightAsync))
{
if(this.applyLinedFlowLayoutOptionsAsync)
{
this.applyLinedFlowLayoutOptionsAsync = false;
ApplyLinedFlowLayoutSettings();
}
if(this.applyLinedFlowLayoutLineHeightAsync)
{
this.applyLinedFlowLayoutLineHeightAsync = false;
ApplyLinedFlowLayoutLineHeight();
}
}
}
#endregion
#region 레이아웃 라디오 버튼 체크시 처리하기 - layoutRadioButton_Checked(sender, e)
/// <summary>
/// 레이아웃 라디오 버튼 체크시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void layoutRadioButton_Checked(object sender, RoutedEventArgs e)
{
if(sender is RadioButton radioButton && this.itemsView != null)
{
switch(radioButton.Content.ToString())
{
case "LinedFlowLayout" :
if(this.linedFlowLayout != null && this.linedFlowLayoutDataTemplate != null)
{
this.itemsView.Layout = this.linedFlowLayout;
this.itemsView.ItemTemplate = this.linedFlowLayoutDataTemplate;
this.linedFlowLayoutSettingStackPanel.Visibility = Visibility.Visible;
this.stackLayoutSettingsStackPanel.Visibility = Visibility.Collapsed;
this.uniformGridLayoutSettingsStackPanel.Visibility = Visibility.Collapsed;
}
break;
case "StackLayout" :
if(this.stackLayout == null)
{
this.stackLayout = new StackLayout() { Spacing = 5 };
}
if(this.stackLayoutDataTemplate == null)
{
this.stackLayoutDataTemplate = this.border.Resources["StackLayoutDataTemplateKey"] as DataTemplate;
}
this.itemsView.Layout = this.stackLayout;
this.itemsView.ItemTemplate = this.stackLayoutDataTemplate;
this.linedFlowLayoutSettingStackPanel.Visibility = Visibility.Collapsed;
this.stackLayoutSettingsStackPanel.Visibility = Visibility.Visible;
this.uniformGridLayoutSettingsStackPanel.Visibility = Visibility.Collapsed;
break;
case "UniformGridLayout" :
if(this.uniformGridLayout == null)
{
this.uniformGridLayout = new UniformGridLayout()
{
MinRowSpacing = 5,
MinColumnSpacing = 5,
MaximumRowsOrColumns = 3
};
}
if(this.uniformGridLayoutDataTemplate == null)
{
this.uniformGridLayoutDataTemplate = this.border.Resources["UniformGridLayoutDataTemplateKey"] as DataTemplate;
}
this.itemsView.Layout = this.uniformGridLayout;
this.itemsView.ItemTemplate = this.uniformGridLayoutDataTemplate;
this.linedFlowLayoutSettingStackPanel.Visibility = Visibility.Collapsed;
this.stackLayoutSettingsStackPanel.Visibility = Visibility.Collapsed;
this.uniformGridLayoutSettingsStackPanel.Visibility = Visibility.Visible;
break;
}
}
}
#endregion
#region 선형 플로우 레이아웃 설정 넘버 박스 값 변경시 처리하기 - linedFlowLayoutSettingsNumberBox_ValueChanged(sender, e)
/// <summary>
/// 선형 플로우 레이아웃 설정 넘버 박스 값 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void linedFlowLayoutSettingsNumberBox_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs e)
{
if(this.itemsView != null && this.itemsView.ScrollView != null && this.itemsView.ScrollView.VerticalOffset != 0)
{
this.itemsView.ScrollView.ScrollTo(0, 0, new ScrollingScrollOptions(ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore));
this.applyLinedFlowLayoutOptionsAsync = true;
}
else
{
ApplyLinedFlowLayoutSettings();
}
}
#endregion
#region 라인 높이 라디오 버튼 체크시 처리하기 - lineHeightRadioButton_Checked(sender, e)
/// <summary>
/// 라인 높이 라디오 버튼 체크시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void lineHeightRadioButton_Checked(object sender, RoutedEventArgs e)
{
if(this.itemsView != null && this.itemsView.ScrollView != null && this.itemsView.ScrollView.VerticalOffset != 0)
{
this.itemsView.ScrollView.ScrollTo(0, 0, new ScrollingScrollOptions(ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore));
this.applyLinedFlowLayoutLineHeightAsync = true;
}
else
{
ApplyLinedFlowLayoutLineHeight();
}
}
#endregion
#region 스택 레이아웃 설정 넘버 박스 값 변경시 처리하기 - stackLayoutSettingsNumberBox_ValueChanged(sender, e)
/// <summary>
/// 스택 레이아웃 설정 넘버 박스 값 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void stackLayoutSettingsNumberBox_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs e)
{
if(this.stackLayout != null)
{
this.stackLayout.Spacing = this.spacingNumberBox.Value;
}
}
#endregion
#region 유니폼 그리드 레이아웃 설정 넘버 박스 값 변경시 처리하기 - uniformGridLayoutSettingsNumberBox_ValueChanged(sender, e)
/// <summary>
/// 유니폼 그리드 레이아웃 설정 넘버 박스 값 변경시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void uniformGridLayoutSettingsNumberBox_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs e)
{
if(this.uniformGridLayout != null)
{
this.uniformGridLayout.MinColumnSpacing = this.minColumnSpacingNumberBox.Value;
this.uniformGridLayout.MinRowSpacing = this.minRowSpacingNumberBox.Value;
this.uniformGridLayout.MaximumRowsOrColumns = (int)this.mximumRowsOrColumnsNumberBox.Value;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 선형 플로우 레이아웃 설정 적용하기 - ApplyLinedFlowLayoutSettings()
/// <summary>
/// 선형 플로우 레이아웃 설정 적용하기
/// </summary>
private void ApplyLinedFlowLayoutSettings()
{
if(this.linedFlowLayout != null && this.lineSpacingNumberBox != null && this.minItemSpacingNumberBox != null)
{
this.linedFlowLayout.LineSpacing = this.lineSpacingNumberBox.Value;
this.linedFlowLayout.MinItemSpacing = this.minItemSpacingNumberBox.Value;
}
}
#endregion
#region 선형 플로우 레이아웃 라인 높이 적용하기 - ApplyLinedFlowLayoutLineHeight()
/// <summary>
/// 선형 플로우 레이아웃 라인 높이 적용하기
/// </summary>
private void ApplyLinedFlowLayoutLineHeight()
{
if(this.linedFlowLayout != null && this.smallLineHeightRadioButton != null)
{
this.linedFlowLayout.LineHeight = (bool)this.smallLineHeightRadioButton.IsChecked ? 80 : 160;
}
}
#endregion
}
}