[C#/WINUI3/.NET6] ListView 클래스 : SelectionMode 속성 사용하기
■ ListView 클래스의 SelectionMode 속성을 사용하는 방법을 보여준다. ▶ NativeHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
using System.Runtime.InteropServices; namespace TestProject { /// <summary> /// 네이티브 헬퍼 /// </summary> public class NativeHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Import ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 현재 패키지 ID 구하기 - GetCurrentPackageId(bufferLength, buffer) /// <summary> /// 현재 패키지 ID 구하기 /// </summary> /// <param name="bufferLength">버퍼 길이</param> /// <param name="buffer">버퍼</param> /// <returns>처리 결과</returns> [DllImport("api-ms-win-appmodel-runtime-l1-1-1", SetLastError = true)] [return : MarshalAs(UnmanagedType.U4)] private static extern uint GetCurrentPackageId(ref int bufferLength, out byte buffer); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// ERROR_SUCCESS /// </summary> public const int ERROR_SUCCESS = 0; /// <summary> /// ERROR_INSUFFICIENT_BUFFER /// </summary> public const int ERROR_INSUFFICIENT_BUFFER = 122; /// <summary> /// APPMODEL_ERROR_NO_PACKAGE /// </summary> public const int APPMODEL_ERROR_NO_PACKAGE = 15700; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 애플리케이션 패키지 여부 - IsAppPackaged /// <summary> /// 애플리케이션 패키지 여부 /// </summary> public static bool IsAppPackaged { get { int bufferSize = 0; uint lastError = GetCurrentPackageId(ref bufferSize, out _); bool isPackaged = true; if(lastError == APPMODEL_ERROR_NO_PACKAGE) { isPackaged = false; } return isPackaged; } } #endregion } } |
▶ FileLoader.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Windows.Storage; namespace TestProject { /// <summary> /// 파일 로더 /// </summary> public class FileLoader { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 텍스트 로드하기 - LoadText(relativeFilePath) /// <summary> /// 텍스트 로드하기 /// </summary> /// <param name="relativeFilePath">상대적인 파일 경로</param> /// <returns>텍스트</returns> public static async Task<string> LoadText(string relativeFilePath) { StorageFile storageFile = null; if(!NativeHelper.IsAppPackaged) { string entryAssemblyFilePath = Assembly.GetEntryAssembly().Location; string entryAssemblyDirectorPath = Path.GetDirectoryName(entryAssemblyFilePath); string filePath = Path.Combine(entryAssemblyDirectorPath, relativeFilePath); string finalFilePath = Path.GetFullPath(filePath); storageFile = await StorageFile.GetFileFromPathAsync(finalFilePath); } else { Uri sourceURI = new Uri($"ms-appx:///{relativeFilePath}"); storageFile = await StorageFile.GetFileFromApplicationUriAsync(sourceURI); } return await FileIO.ReadTextAsync(storageFile); } #endregion #region 라인 리스트 로드하기 - LoadLineList(relativeFilePath) /// <summary> /// 라인 리스트 로드하기 /// </summary> /// <param name="relativeFilePath">상대적인 파일 경로</param> /// <returns>라인 리스트</returns> public static async Task<IList<string>> LoadLineList(string relativeFilePath) { string text = await LoadText(relativeFilePath); return text.Split(Environment.NewLine).ToList(); } #endregion } } |
▶ GroupInfoList.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
using System.Collections.Generic; namespace TestProject { /// <summary> /// 그룹 정보 리스트 /// </summary> public class GroupInfoList : List<object> { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 키 - Key /// <summary> /// 키 /// </summary> public object Key { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - GroupInfoList(itemEnumerable) /// <summary> /// 생성자 /// </summary> /// <param name="itemEnumerable">항목 열거 가능형</param> public GroupInfoList(IEnumerable<object> itemEnumerable) : base(itemEnumerable) { } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 문자열 구하기 - ToString() /// <summary> /// 문자열 구하기 /// </summary> /// <returns></returns> public override string ToString() { return $"Group {Key}"; } #endregion } } |
▶ Contact.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; namespace TestProject { /// <summary> /// 연락처 /// </summary> public class Contact { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 이름 - FirstName /// <summary> /// 이름 /// </summary> public string FirstName { get; private set; } #endregion #region 성 - LastName /// <summary> /// 성 /// </summary> public string LastName { get; private set; } #endregion #region 회사 - Company /// <summary> /// 회사 /// </summary> public string Company { get; private set; } #endregion #region 성명 - Name /// <summary> /// 성명 /// </summary> public string Name => $"{FirstName} {LastName}"; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - Contact(firstName, lastName, company) /// <summary> /// 생성자 /// </summary> /// <param name="firstName">이름</param> /// <param name="lastName">성</param> /// <param name="company">회사</param> public Contact(string firstName, string lastName, string company) { FirstName = firstName; LastName = lastName; Company = company; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 연락처 컬렉션 구하기 (비동기) - GetContactCollectionAsync() /// <summary> /// 연락처 컬렉션 구하기 (비동기) /// </summary> /// <returns>연락처 컬렉션 태스크</returns> public async static Task<ObservableCollection<Contact>> GetContactCollectionAsync() { IList<string> lineList = await FileLoader.LoadLineList("DATA/Contacts.txt"); ObservableCollection<Contact> contactCollection = new ObservableCollection<Contact>(); for(int i = 0; i < lineList.Count - 2; i += 3) { contactCollection.Add(new Contact(lineList[i], lineList[i + 1], lineList[i + 2])); } return contactCollection; } #endregion #region 그룹 연락처 컬렉션 구하기 (비동기) - GetGroupedContactCollectionAsync() /// <summary> /// 그룹 연락처 컬렉션 구하기 (비동기) /// </summary> /// <returns>그룹 연락처 컬렉션 태스크</returns> public static async Task<ObservableCollection<GroupInfoList>> GetGroupedContactCollectionAsync() { var query = from item in await GetContactCollectionAsync() group item by item.LastName.Substring(0, 1).ToUpper() into g orderby g.Key select new GroupInfoList(g) { Key = g.Key }; return new ObservableCollection<GroupInfoList>(query); } #endregion #region 문자열 구하기 - ToString() /// <summary> /// 문자열 구하기 /// </summary> /// <returns>문자열</returns> public override string ToString() { return Name; } #endregion } } |
▶ MainWindow.xaml