수색…


비고

UserControl은 Control과 매우 다릅니다. 주요 차이점 중 하나는 UserControl이 XAML 레이아웃 파일을 사용하여 여러 개별 컨트롤을 배치 할 위치를 결정한다는 점입니다. 반면 컨트롤은 순수한 코드 일뿐입니다. 레이아웃 파일이 전혀 없습니다. 어떤면에서는 사용자 정의 컨트롤을 만드는 것이 사용자 정의 UserControl을 만드는 것보다 효과적 일 수 있습니다.

사용자 정의 기본 텍스트가있는 ComboBox

이 사용자 지정 UserControl은 일반 콤보 상자로 표시되지만 기본 제공 ComboBox 개체와 달리 아직 선택하지 않은 경우 사용자에게 기본 텍스트 문자열을 표시 할 수 있습니다.

이를 위해 UserControl은 두 개의 컨트롤로 구성됩니다. 분명히 실제 ComboBox가 필요하지만 일반 Label을 사용하여 기본 텍스트를 표시합니다.


CustomComboBox.xaml

<UserControl x:Class="UserControlDemo.CustomComboBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:cnvrt="clr-namespace:UserControlDemo"
             x:Name="customComboBox">
    <UserControl.Resources>
        <cnvrt:InverseNullVisibilityConverter x:Key="invNullVisibleConverter" />
    </UserControl.Resources>
    <Grid>
        <ComboBox x:Name="comboBox"
                  ItemsSource="{Binding ElementName=customComboBox, Path=MyItemsSource}"
                  SelectedItem="{Binding ElementName=customComboBox, Path=MySelectedItem}"
                  HorizontalContentAlignment="Left" VerticalContentAlignment="Center"/>
        
        <Label HorizontalAlignment="Left" VerticalAlignment="Center"
               Margin="0,2,20,2" IsHitTestVisible="False"
               Content="{Binding ElementName=customComboBox, Path=DefaultText}"
               Visibility="{Binding ElementName=comboBox, Path=SelectedItem, Converter={StaticResource invNullVisibleConverter}}"/>
    </Grid>
</UserControl>

보시다시피이 단일 UserControl은 실제로 두 개의 개별 컨트롤 그룹입니다. 이렇게하면 하나의 ComboBox만으로는 사용할 수없는 유연성이 생깁니다.

주목해야 할 몇 가지 중요한 사항이 있습니다.

  • UserControl 자체에는 x:Name 집합이 있습니다. 이것은 코드 숨김에있는 속성에 바인딩하기를 원하기 때문입니다. 즉, 코드 자체를 참조 할 수있는 방법이 필요합니다.
  • ComboBox의 각 바인딩에는 ElementName 으로 UserControl의 이름이 있습니다. 이것은 UserControl이 바인딩을 찾기 위해 스스로를 인식 할 수 있도록하기위한 것입니다.
  • 라벨이 눈에 띄지 않습니다. 이것은 Label이 ComboBox의 일부임을 사용자에게 알리기위한 것입니다. IsHitTestVisible=false 로 설정하면 사용자가 마우스를 IsHitTestVisible=false 거나 라벨을 클릭하지 못하게됩니다. 모든 입력은 아래의 ComboBox로 전달됩니다.
  • Label은 InverseNullVisibility 변환기를 사용하여 표시 여부를 결정합니다. 이 코드의 하단에이 코드가 있습니다.

CustomComboBox.xaml.cs

public partial class CustomComboBox : UserControl
{
    public CustomComboBox()
    {
        InitializeComponent();
    }

    public static DependencyProperty DefaultTextProperty =
        DependencyProperty.Register("DefaultText", typeof(string), typeof(CustomComboBox));

    public static DependencyProperty MyItemsSourceProperty = 
        DependencyProperty.Register("MyItemsSource", typeof(IEnumerable), typeof(CustomComboBox));

    public static DependencyProperty SelectedItemProperty =
        DependencyProperty.Register("SelectedItem", typeof(object), typeof(CustomComboBox));

    public string DefaultText
    {
        get { return (string)GetValue(DefaultTextProperty); }
        set { SetValue(DefaultTextProperty, value); }
    }

    public IEnumerable MyItemsSource
    {
        get { return (IEnumerable)GetValue(MyItemsSourceProperty); }
        set { SetValue(MyItemsSourceProperty, value); }
    }

    public object MySelectedItem
    {
        get { return GetValue(MySelectedItemProperty); }
        set { SetValue(MySelectedItemProperty, value); }
    }
}

코드 숨김에서 우리는이 UserControl을 사용하여 프로그래머가 사용할 수있는 속성을 단순히 노출하고 있습니다. 불행히도이 클래스 외부에서 ComboBox에 직접 액세스 할 수 없으므로 중복 속성 (예 : ComboBox의 ItemsSource 에 대한 MyItemsSource 을 노출해야합니다. 그러나 이것은 네이티브 컨트롤과 유사하게 사용할 수 있다는 점을 고려할 때 약간의 단점이 있습니다.


CustomComboBox UserControl을 사용하는 방법은 다음과 같습니다.

<Window x:Class="UserControlDemo.UserControlDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cntrls="clr-namespace:UserControlDemo"
        Title="UserControlDemo" Height="240" Width=200>
    <Grid>
        <cntrls:CustomComboBox HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="165"
                               MyItemsSource="{Binding Options}"
                               MySelectedItem="{Binding SelectedOption, Mode=TwoWay}"
                               DefaultText="Select an option..."/>
    <Grid>
</Window>

그리고 최종 결과 :

그림 1 여기에 이미지 설명을 입력하십시오. 그림 3


다음은 InverNullVisibilityConverter가 UserControl의 Label에 필요한 기능입니다. 이 버전lll의 버전을 약간 변형 한 것입니다.

public class InverseNullVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? Visibility.Visible : Visibility.Hidden;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow