Freezable

์ฐธ์กฐ ์‚ฌ์ดํŠธ : WPF : 8. DataGridColumn์˜ Visibility ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๋ฐฉ๋ฒ• - LCโ€™s ๊ฐœ๋ฐœ ๋ธ”๋กœ๊ทธ

์šฐ์„  ์ฝ”๋“œ๋ฅผ ๋จผ์ € ์ ์ž๋ฉด

        <DataGrid CanUserAddRows="False" CanUserDeleteRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="Column1" Header="Column1" />
                <DataGridTextColumn Header="Column2" Visibility="{Binding Column2Visible, Converter={StaticResource BoolToVisibilityConverter}}" />
            </DataGrid.Columns>
        </DataGrid>
        <CheckBox Content="Column Visible" IsChecked="{Binding Column2Visible, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="Test" Visibility="{Binding Column2Visible, Converter={StaticResource BoolToVisibilityConverter}}" />

ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋ฉด TextBlock๋Š” ์ •์ƒ์ ์œผ๋กœ Visible์ด ๋ณ€๊ฒฝ ๋˜๋Š”๋ฐ Column์€ ๋ณ€๊ฒฝ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. 

๊ฐ€ ๋ฐœ์ƒ ํ•ฉ๋‹ˆ๋‹ค.

ํ™•์ธํ•ด ๋ณด๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ ํ•ด ๋ณด๋ฉด

// xaml
        <Button
            Command="{Binding TestCommand}"
            CommandParameter="{Binding ElementName=Column1}"
            Content="Test" />
// cs
	private void Test(DataGridTextColumn column)
	{
		try
		{
			VisualTreeHelper.GetParent(column);
		}
		catch (Exception ex)
		{
			MessageBox.Show(ex.Message);
		}
	}

image
์™€ ๊ฐ™์€ exception์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•˜๊ธฐ ์œ„ํ•ด์„  Freezable์„ ๊ฐ€์ ธ๋‹ค ์“ฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

// xaml
        <DataGrid CanUserAddRows="False" CanUserDeleteRows="False">
            <DataGrid.Resources>
                <local:VisibleBindingProxy x:Key="Culmn2VisiblePlory" Visible="{Binding Column2Visible, Converter={StaticResource BoolToVisibilityConverter}}" />
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="Column1" Header="Column1" />
                <DataGridTextColumn Header="Column2" Visibility="{Binding Visible, Source={StaticResource Culmn2VisiblePlory}}" />
            </DataGrid.Columns>
        </DataGrid>
        <CheckBox Content="Column Visible" IsChecked="{Binding Column2Visible, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="Test" Visibility="{Binding Column2Visible, Converter={StaticResource BoolToVisibilityConverter}}" />

// cs
public class VisibleBindingProxy : Freezable
{
	public Visibility Visible
	{
		get { return (Visibility)GetValue(VisibleProperty); }
		set { SetValue(VisibleProperty, value); }
	}
	public static readonly DependencyProperty VisibleProperty =
		DependencyProperty.Register("Visible", typeof(Visibility), typeof(VisibleBindingProxy), new PropertyMetadata(Visibility.Visible));
	protected override Freezable CreateInstanceCore()
	{
		return new VisibleBindingProxy();
	}
}
3๊ฐœ์˜ ์ข‹์•„์š”

์•„์ง Freezable์„ ์•Œ๊ณ  ์จ๋ณธ์ ์ด ์—†๋Š”๋ฐ, ํ˜น์‹œ ๋Œ€๋žต์ ์œผ๋กœ ์ดํ•ดํ•˜์‹  ๋ฐ”๋ฅผ ์•Œ๋ ค์ฃผ์‹ค ์ˆ˜ ์žˆ์œผ์‹ค๊นŒ์š”?

MSDN์„ ๋ณด๋ฉด ๋ฌด์Šจ๋ง์ธ์ง€โ€ฆ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค ใ… ใ… 

1๊ฐœ์˜ ์ข‹์•„์š”

DataGridColumn ์ž์ฒด๋Š” VisualTree์— ์ฐธ์—ฌํ•˜๊ณ  ์žˆ์ง€ ์•Š์„๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ DataContext ์—์„œ ๋ฐ”์ธ๋”ฉ ํŒจ์Šค ์ฐพ๊ธฐ๋Š” ์‹คํŒจํ•˜๋‹ˆ, ๊ฐ„์ ‘์ ์œผ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ์Šค๋กœ ํ•ด์„œ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•„์˜ค๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฅผ ์œ„ํ•ด์„œ Freezable ์„ ์ƒ์† ๋ฐ›์•„ ๊ตฌํ˜„ํ•˜๊ณ  ๋ฆฌ์†Œ์Šค๋ฅผ ์„ ์–ธํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Freezable์˜ ๋ถ€๋ชจ์ธ DependenyObject ๋ฅผ ์ƒ์† ๋ฐ›์•„๋„ ๋˜๋Š”๋ฐ์š”. Freezable์„ ๋ฐ›์œผ๋ฉด ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋กœ ์„ ์–ธํ•จ์œผ๋กœ์จ ์ชผ๊ธˆ ๋” ํ™œ์šฉํ•  ์—ฌ์ง€๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค.

3๊ฐœ์˜ ์ข‹์•„์š”

Freezable์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ด๋ฒคํŠธ ๋ฐ ์Šคํ† ๋ฆฌ๋ณด๋“œ(์• ๋‹ˆ๋ฉ”์ด์…˜) ๋ณ€๊ฒฝ ์ถ”์ ์„ ์ œ๊ณต ํ•ฉ๋‹ˆ๋‹ค.

Freezable.Changed ์ด๋ฒคํŠธ (System.Windows) | ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ ๋Ÿฐ(Microsoft T


Freezable์€ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ CanFreeze ์†์„ฑ์œผ๋กœ ๊ณ ์ • ๋˜์–ด ์žˆ๋‹ค๋ฉด

ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ ๋˜์—ˆ์„๋•Œ ๋ฐ”์ธ๋”ฉ์‹œ ํ†ต๋ณด๋ฅผ ํ•˜์ง€ ์•Š์ง€๋งŒ,

๊ณ ์ • ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด ๋ฐ”์ธ๋”ฉ์‹œ ๋ถ€๋ชจ ๊ด€์ฐฐ์ž์—๊ฒŒ ํ†ต๋ณด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋•Œ๋ฌธ์— Freezable์„ ์ƒ์† ๋ฐ›์Œ ์œผ๋กœ์จ DataGridColumn ๊นŒ์ง€ ๋ณ€๊ฒฝ ํ†ต๋ณด ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์–ด ์ •์ƒ์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉ์ด ์ฒ˜๋ฆฌ ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

์•„ํ•˜ ์š”์•ฝํ•˜์ž๋ฉด ๋ฐ”์ธ๋”ฉ ๋œ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์›๋ž˜๋ผ๋ฉด Notify๋ฅผ ์ค„ ์ˆ˜ ์—†๋Š” ์ปจํŠธ๋กค์— ๋Œ€ํ•ด์„œ, Notify๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๊ฒƒ์ด๊ตฐ์š”.

ChatGPT๋ฅผ ํ†ตํ•ด BindingProxy๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•œ ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ ๊ทธ๋ž˜์„œ ๊ฐ€๋Šฅํ–ˆ๋˜ ๊ฒƒ์ด๊ตฐ์š”.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

1๊ฐœ์˜ ์ข‹์•„์š”