Как сделать так, чтобы RadioButton's Bullet выравнивал верх? - PullRequest
11 голосов
/ 10 февраля 2009

У меня есть многострочная радиокнопка, и я хочу, чтобы маркер располагался слева от содержимого (по умолчанию), выровненного по верху радиокнопки. Какой самый простой способ сделать это в XAML?

Ответы [ 3 ]

17 голосов
/ 19 октября 2011

Примечание : Обязательно ознакомьтесь с ответом Рэйчел - она ​​продвинулась еще на один этап в общий шаблон


Прежде всего, не тратьте свое время на VerticalAlignment или VerticalContentAlignment (или даже ControlTemplate). Они не будут делать то, что вы хотите или могли бы ожидать.

Как описано в MSDN a BulletDecorator (это элемент управления, который CheckBox и RadioButton используют для рендеринга радио / кнопки проверки) автоматически установит положение значка. У вас нет дополнительного контроля над этим:

Пуля всегда выравнивается по первой строке текста, когда ребенок Объект является текстовым объектом. Если дочерний объект не является текстовым объектом, Пуля выравнивается по центру дочернего объекта.

Если вы не измените шаблон управления (необязательно), вы сможете разместить значок радио / галочки в верхней части только в том случае, если содержимое является текстом.

Так что если вы сделаете что-то подобное, это не будет хорошо выглядеть, потому что вы не сможете перемещать значок независимо от того, сколько VerticalAlignment свойств вы пытаетесь установить.

<RadioButton>
    <StackPanel>
        <TextBlock Text="First line"/>
        <TextBlock Text="Something else"/>
    </StackPanel>
</RadioButton>

НО к счастью, вы можете положить почти все, что захотите, в TextBlock, используя InlineUIContainer. Текст (или содержимое) в первой строке будет автоматически определять положение значка. Если вы хотите что-то под первой строкой, которая не является текстом, просто используйте <Linebreak/>, а затем <InlineUIContainer/>

Вот пример с увеличенным TextBox, чтобы более четко показать, что происходит.

<RadioButton>

    <TextBlock VerticalAlignment="Top" TextWrapping="Wrap">

        <TextBlock Text="Products with &lt;" VerticalAlignment="Center" Margin="0,0,5,0"/>

        <InlineUIContainer BaselineAlignment="Center">
            <TextBox FontSize="30" Width="25" Text="10" Margin="0,0,5,0"/>          
        </InlineUIContainer>

        <TextBlock VerticalAlignment="Center" Margin="0,0,5,0">
            <Run Text="days" FontWeight="Bold"/>
            <Run Text="inventory" />
        </TextBlock>

        <LineBreak/>    

        <InlineUIContainer>
            <StackPanel>
                <CheckBox Content="Include unsold products" />
                <CheckBox Content="Include something else" />
            </StackPanel>
        </InlineUIContainer>

    </TextBlock>
</RadioButton>
14 голосов
/ 02 мая 2013

Я создал относительно общий шаблон, основанный на ответе Саймона Уивера , который можно использовать в большинстве ситуаций без необходимости постоянно настраивать RadioButton.Content.

<ControlTemplate x:Key="MultiLineRadioButtonTemplate" TargetType="{x:Type RadioButton}">
    <RadioButton IsChecked="{TemplateBinding IsChecked}">
        <TextBlock>
            <LineBreak />
            <InlineUIContainer>
                <ContentPresenter Margin="0,-21,0,8" 
                                  Content="{TemplateBinding ContentPresenter.Content}"
                                  ContentTemplate="{TemplateBinding ContentPresenter.ContentTemplate}"/>
            </InlineUIContainer>
        </TextBlock>
    </RadioButton>
</ControlTemplate>

Чтобы объяснить, как работает шаблон:

  • TextBlock есть, потому что по умолчанию маркер RadioButton выравнивается с первой строкой текста, если содержимое является текстовым объектом (a Label не будет работать)

  • LineBreak - перенос содержимого на новую строку, поэтому создается первая строка

  • InlineUIContainer позволяет размещать нетекстовый контент в TextBlock

  • * * * * * * * * * * * * * ContentPresenter * * * * * * * * * * * * * * * * * * * * [1030] * * * * * * * * * * * * *

    * * * * * * * * * * * * * * * * * * * * * * * * * 1030

Вот пример содержимого:

<StackPanel>
    <RadioButton Template="{StaticResource MultiLineRadioButtonTemplate}">
        <StackPanel>
            <Label Content="Option 1" />
            <StackPanel>
                <CheckBox Content="Some setting" />
                <CheckBox Content="Some other setting" />
            </StackPanel>
        </StackPanel>
    </RadioButton>

    <RadioButton Template="{StaticResource MultiLineRadioButtonTemplate}">
        <StackPanel>
            <Label Content="Option 2" />
            <DataGrid AutoGenerateColumns="False" Height="100">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Id" />
                    <DataGridTextColumn Header="Date" />
                    <DataGridTextColumn Header="Total" />
                    <DataGridTextColumn Header="Count" />
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </RadioButton>


    <RadioButton Template="{StaticResource MultiLineRadioButtonTemplate}">
        <StackPanel>
            <Label Content="Option 3" />
            <TextBlock TextWrapping="WrapWithOverflow" Margin="2">
                Lorem ipsum dolor sit amet, consectetur adipisicing elit, 
                sed do eiusmod tempor incididunt ut labore et dolore magna 
                aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
                ullamco laboris nisi ut aliquip ex ea commodo consequat. 
                Duis aute irure dolor in reprehenderit in voluptate velit 
                esse cillum dolore eu fugiat nulla pariatur. Excepteur sint 
                occaecat cupidatat non proident, sunt in culpa qui officia 
                deserunt mollit anim id est laborum.
            </TextBlock>
        </StackPanel>
    </RadioButton>
</StackPanel>

А как это выглядит:

enter image description here

Единственное, что меня действительно не устраивает, - это отрицательное верхнее поле для жестко запрограммированного ContentPresenter, потому что если вы когда-нибудь измените размер шрифта, вам придется вручную отрегулировать это поле.

Вероятно, было бы не так сложно создать конвертер для свойства Margin, которое вычисляет высоту разрыва строки ({TemplateBinding FontSize}?), Или даже расширенной версии элемента управления RadioButton, который имеет такое поведение по по умолчанию, но сейчас я в порядке с жестким кодированием -21, основанным на размере шрифта моего приложения по умолчанию.

Кроме того, вы можете добавить TemplateBindings к RadioButton в шаблоне, если вы хотите наследовать другие свойства от исходного RadioButton, такие как поля, отступы, выравнивание и т. Д. Я ограничен только IsChecked для простоты.

2 голосов
/ 10 февраля 2009

Переопределить Control.Template для RadioButton. Вот пример из MSDN Пример шаблона кнопки управления переключателем

Если вы не хотите переопределять шаблон Control.Tample для переключателя, вы можете сделать содержимое обернутым текстовым блоком. посмотрите этот образец

<RadioButton  Name="radioButton1">
    <TextBlock TextWrapping="Wrap">Here is some multiline text that does some wrapping</TextBlock>
</RadioButton>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...