サーチ…


備考

UserControlはControlと非常に異なることに注意してください。主な違いの1つは、UserControlがXAMLレイアウトファイルを使用して、複数の個々のコントロールを配置する場所を決定することです。一方、コントロールは純粋なコードです。レイアウトファイルはまったくありません。カスタムコントロールを作成する方が、カスタムのUserControlを作成するより効果的です。

カスタムデフォルトテキストを持つComboBox

このカスタムUserControlは通常のコンボボックスとして表示されますが、組み込みのComboBoxオブジェクトとは異なり、ユーザーがまだ選択を行っていない場合は、デフォルトの文字列を表示できます。

これを達成するために、私たちのUserControlは2つのコントロールで構成されます。明らかに実際の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は、実際には2つの個別コントロールのグループです。これにより、1つのComboBoxだけでは利用できない柔軟性が実現します。

注意すべきいくつかの重要なことがあります:

  • UserControl自体にはx:Name設定されています。これは、コードビハインドにあるプロパティにバインドする必要があるためです。つまり、コードビハインドを参照する方法が必要です。
  • ComboBox上の各バインディングは、 ElementNameとしてUserControlの名前を持ちます。これは、UserControlがバインディングを見つけるために自分自身を見ることを知るようにするためです。
  • ラベルはヒットテストでは表示されません。これは、LabelがComboBoxの一部であるという錯覚をユーザに与えるためです。 IsHitTestVisible=false設定すると、ユーザーがラベル上にIsHitTestVisible=falseことやラベルをクリックすることを禁止します。すべての入力は、下のComboBoxに渡されます。
  • ラベルは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に直接アクセスすることはできないため、重複したプロパティ( MyItemsSource 、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


ここでは、UserControlのLabelに必要なInverseNullVisibilityConverterがありますが、これは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