๐ WPF TreeView ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ
TreeView๊ฐ ์ปค์ง์๋ก ์ํ๋ ๋ ธ๋๋ฅผ ์ฐพ๊ธฐ ์ด๋ ค์์ง๋๋ค. ์ด๋ฒ ํฌ์คํธ์์๋ TreeView์ ๊ฒ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ฌ ์ฌ์ฉ์๊ฐ ํ ์คํธ๋ฅผ ์ ๋ ฅํ๋ฉด ๊ด๋ จ ๋ ธ๋๋ง ํ์๋๋๋ก ๋ง๋ค์ด๋ด ๋๋ค.
๋ชฉ์ฐจ
1. ๊ฒ์ ์ ๋ ฅ UI ๋ง๋ค๊ธฐ
<StackPanel>
<TextBox Width="300" Margin="10"
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"
PlaceholderText="๋
ธ๋ ๊ฒ์..." />
<TreeView ItemsSource="{Binding FilteredCategories}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
์ฌ์ฉ์์ ์ ๋ ฅ์ ViewModel๋ก ๋ฐ์ธ๋ฉํฉ๋๋ค.
2. ViewModel์์ ํํฐ๋ง ์ฒ๋ฆฌ
private ObservableCollection<Category> _allCategories;
public ObservableCollection<Category> FilteredCategories { get; set; } = new();
private string _searchText = "";
public string SearchText
{
get => _searchText;
set
{
_searchText = value;
OnPropertyChanged();
FilterTree();
}
}
private void FilterTree()
{
FilteredCategories.Clear();
foreach (var cat in _allCategories)
{
var copy = FilterCategory(cat, _searchText);
if (copy != null)
FilteredCategories.Add(copy);
}
}
private Category? FilterCategory(Category cat, string keyword)
{
var matchedChildren = cat.Children
.Select(child => FilterCategory(child, keyword))
.Where(c => c != null)
.ToList();
bool isMatch = cat.Name.Contains(keyword, StringComparison.OrdinalIgnoreCase);
if (isMatch || matchedChildren.Count > 0)
{
return new Category
{
Name = cat.Name,
Children = new ObservableCollection<Category>(matchedChildren)
};
}
return null;
}
ํธ๋ฆฌ๋ฅผ ์ฌ๊ท์ ์ผ๋ก ํ์ํ๋ฉด์ ํค์๋์ ์ผ์นํ๊ฑฐ๋ ์์ ์ค์ ์ผ์นํ๋ ๋ ธ๋๋ฅผ ๋ณต์ฌํ์ฌ ๊ตฌ์ฑํฉ๋๋ค.
3. ๊ฒ์ ๊ฒฐ๊ณผ ์๋ ํ์ฅ
ํํฐ๋ง๋ ํธ๋ฆฌ ํญ๋ชฉ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ ค ์์ง ์๊ธฐ ๋๋ฌธ์, ์ฌ์ฉ์ ๊ฒฝํ์ ์ํด ๋ ธ๋๊ฐ ์๋์ผ๋ก ํ์ฅ๋๋๋ก ์ถ๊ฐ ์์ ์ด ํ์ํฉ๋๋ค.
public class Category : INotifyPropertyChanged
{
public string Name { get; set; }
public ObservableCollection<Category> Children { get; set; } = new();
private bool _isExpanded = false;
public bool IsExpanded
{
get => _isExpanded;
set { _isExpanded = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
๊ฒ์ ์ ๊ฒฐ๊ณผ๋ฅผ ์ํํ๋ฉด์ IsExpanded = true
๋ฅผ ์ค์ ํด์ฃผ๋ฉด ์๋ ํ์ฅ์ด ๊ฐ๋ฅํฉ๋๋ค.
4. ์ ๋ฆฌ ๋ฐ ํ์ฅ ์์ด๋์ด
- TreeView์์ ์ค์๊ฐ ๊ฒ์์ ํตํด UX๋ฅผ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค
- ๊ฒ์์ด ํ์ด๋ผ์ดํธ ๊ธฐ๋ฅ ์ถ๊ฐ ๊ฐ๋ฅ (TextBlock ์คํ์ผ ๋ณ๊ฒฝ)
- ๊ฒ์ ๊ฒฐ๊ณผ ์ ํ ์ ํด๋น ๋ ธ๋๋ฅผ ๊ฐ์กฐํ๊ฑฐ๋ ์๋ ์คํฌ๋กค ๊ธฐ๋ฅ๋ ๊ตฌํ ๊ฐ๋ฅ
๋ค์ ํธ์์๋ TreeView์์ ์ฒดํฌ๋ฐ์ค ๋ ธ๋๋ฅผ ๊ตฌํํ๊ณ , ์์/ํ์ ๋ ธ๋๊ฐ ์๋์ผ๋ก ์ฒดํฌ๋๋๋ก ์ฐ๊ฒฐํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค! โ
'C#' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ WPF TreeView์์ ContextMenu๋ก ๋ ธ๋ ์กฐ์ ๊ธฐ๋ฅ ๊ตฌํ (0) | 2025.04.23 |
---|---|
โ WPF TreeView ์ฒดํฌ๋ฐ์ค ๋ ธ๋ ๊ตฌํ ๋ฐ ์๋ ์ฒดํฌ (0) | 2025.04.22 |
WPF TreeView ContextMenu๋ก ๋ ธ๋ ์ญ์ ๋ฐ ์ด๋ฆ ๋ณ๊ฒฝ (0) | 2025.04.15 |
WPF TreeView ๋๋๊ทธ ์ค ๋๋กญ ๊ธฐ๋ฅ ๊ตฌํ (0) | 2025.04.14 |
WPF TreeView ์ ํ ์ํ ์ ์ฅ ๋ฐ ๋ณต์ (0) | 2025.04.13 |