본문 바로가기
닷넷/WPF

Custom UserControl의 바인딩 처리

by hyperhand 2015. 9. 8.

단순히 ON/OFF 상태를 표시할 수 있는 UserControl을 하나 만들었다.

// Code behind

public partial class LEDControl : UserControl

{

public bool IsOn

{

get { return (bool)GetValue(IsOnProperty); }

set { SetValue(IsOnProperty, value); }

}

public static readonly DependencyProperty IsOnProperty = DependencyProperty.Register("IsOn", typeof(bool), typeof(LEDControl), new FrameworkPropertyMetadata(default(bool)));

 

public LEDControl

{

InitializeComponent();

this.DataContext = this;

}

}

 

 

// XAML

<UserControl x:Class="ControlDemo.LEDControl"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 

xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

xmlns:Converter="clr-namespace:ControlDemo.Converters"

mc:Ignorable="d"

d:DesignHeight="48" d:DesignWidth="48">

 

<UserControl.Resources>

<Converter:BoolToOnOffConverter x:Key="BoolToOnOff"/>

</UserControl.Resources>

 

<Ellipse Fill={Binding IsOn, Converter={StaticResource BoolToOnOff}}/>

 

</UserControl>

 

위와 같은 상태에서 윈도우나 또다른 UserControl에서 가져다 쓸 땐 아래처럼 쓴다.

 

// XAML

<Window

...

xmlns:LibControl="clr-namespace:ControlDemo"

... >

 

<LibControl:LEDControl x:Name="led"/>

 

</Window>

 

// Code behind

led.IsOn = true;

 

 

 

 

 

 

그런데 LEDControl의 IsOn Property에 바인딩을 하고자 하면 LEDControl 로드시 아래와 같은 에러 메시지를 만나게 된다.

// XAML

<Window

...

xmlns:LibControl="clr-namespace:ControlDemo"

... >

 

<LibControl:LEDControl IsOn={Binding IsDigitalOut1On}/>

 

</Window>

 

// Code behind

public partial class MyWindow : Window, INotifyPropertyChanged

{

public bool IsDigital1On { get; set; }

 

public MyWindow()

{

InitializeComponent();

this.DataContext = this;

}

}

System.Windows.Data Error: 39 : BindingExpression path error: ...

 

UserControl 내부에서 의존속성을 DataContext를 설정하여 업데이트 하도록 한 뒤, 그 UserControl을 사용하는 측에서 또 DataContext로 속성을 업데이트 하려고 하니 에러가 난다. 이유는 모르겠지만 이리저리 수정해보고 구글링을 해본 결과 UserControl의 의존 속성 업데이트를 DataContext를 설정하는 방법으로 하지 않고, 아래와 같이 최상위 컨트롤에 Name 속성을 설정하고, ElementName으로 해당 속성의 대상을 지정하도록 하면 된다.

 굵은 글씨로 표현된 부분이 변경된 부분이다.

// Code behind

public partial class LEDControl : UserControl

{

public bool IsOn

{

get { return (bool)GetValue(IsOnProperty); }

set { SetValue(IsOnProperty, value); }

}

public static readonly DependencyProperty IsOnProperty = DependencyProperty.Register("IsOn", typeof(bool), typeof(LEDControl), new FrameworkPropertyMetadata(default(bool)));

 

public LEDControl

{

InitializeComponent();

//this.DataContext = this;

}

}

 

// XAML

<UserControl x:Class="ControlDemo.LEDControl"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 

xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

xmlns:Converter="clr-namespace:ControlDemo.Converters"

mc:Ignorable="d"

x:Name="uc"

d:DesignHeight="48" d:DesignWidth="48">

 

<UserControl.Resources>

<Converter:BoolToOnOffConverter x:Key="BoolToOnOff"/>

</UserControl.Resources>

 

<Ellipse Fill={Binding IsOn, Converter={StaticResource BoolToOnOff}, ElementName=uc}/>

 

</UserControl>

 

반응형