WPF: метка для TextBox при выборе - PullRequest
3 голосов
/ 06 апреля 2010

Я хотел бы создать простой дизайнер, который будет выглядеть как визуальная студия. В частности, я бы хотел, чтобы мои элементы имели то же поведение, что и в VS: когда они не выбраны, отображается простой ярлык / текстовый блок, когда они выделены, текстовое поле позволяет мне редактировать значение. Какой лучший способ добиться этого?

Спасибо

Ответы [ 2 ]

4 голосов
/ 06 апреля 2010

создайте шаблон элемента управления для TextBox и измените внешний вид TextBox так, как вам нравится, когда элемент управления сфокусирован или в нем есть содержимое.

0 голосов
/ 29 февраля 2012

Я знаю слишком поздно, но для будущей аудитории:

В этом решении используется оригинальный шаблон элемента управления TextBox и добавлена ​​функциональность, которая заменяет значение свойства Text на свойство Tag TextBox, когда TextBox Text - Пустой . Это довольно сложный стиль, но он работает! (без кода!):

<Style x:Key="TextBoxPlaceHolder" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Padding" Value="1"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
    <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
                    <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Microsoft_Windows_Themes:ListBoxChrome>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                    <Trigger Property="IsFocused" Value="False">
                        <Setter Property="Text">
                            <Setter.Value>
                                <MultiBinding Converter="{StaticResource TextBoxPlaceHolderConverter}">
                                    <Binding RelativeSource="{RelativeSource Self}" Path="Text" />
                                    <Binding RelativeSource="{RelativeSource Self}" Path="Tag" />
                                </MultiBinding>
                            </Setter.Value>
                        </Setter>                                   
                    </Trigger>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="Text">
                            <Setter.Value>
                                <MultiBinding Converter="{StaticResource TextBoxPlaceHolderConverter}" ConverterParameter="True">
                                    <Binding RelativeSource="{RelativeSource Self}" Path="Text" />
                                    <Binding RelativeSource="{RelativeSource Self}" Path="Tag" />
                                </MultiBinding>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Value="True">
                                <Condition.Binding>
                                    <MultiBinding Converter="{StaticResource StringsEqualMultiConverter}" Mode="OneWay">
                                        <Binding RelativeSource="{RelativeSource Self}" Path="Text" />
                                        <Binding RelativeSource="{RelativeSource Self}" Path="Tag" />
                                    </MultiBinding>
                                </Condition.Binding>
                            </Condition>
                            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsFocused}" Value="False"/>
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Foreground" Value="#FF7C7C80"/>
                        <Setter Property="FontStyle" Value="Italic"/>
                    </MultiDataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

И два предоставленных преобразователя:

public class TextBoxPlaceHolderConverter : IMultiValueConverter
{
    private static object s_OriginalTag;

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        s_OriginalTag = values[1];
        var actualText = values[0] as string;
        var textToReturn = actualText ?? string.Empty;
        var tagText = values[1] is string ? values[1] as string : null;
        if (!(parameter is string && parameter.ToString() == "True"))
        {
            if (actualText != null && tagText != null)
            {
                if (actualText.Length == 0) // no text
                {
                    textToReturn = tagText;
                }
                else
                {
                    textToReturn = actualText;
                }
            }
        }
        else
        {
            if (actualText == tagText)
            {
                textToReturn = string.Empty;
            }
        }

        return textToReturn;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        object[] toReturn = new object[2];
        toReturn[0] = value;
        toReturn[1] = s_OriginalTag;

        return toReturn;
    }
}

public class StringsEqualMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var stringToCompare = string.Empty;

        if (values != null)
        {
            if (values.Length > 0 && values[0] is string)
            {
                stringToCompare = values[0] as string;
            }
        }

        var boolToReturn = values.Aggregate(true, (current, value) => current && (value is string && value.ToString().Equals(stringToCompare)));
        return boolToReturn;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...