WPF: Genişliği (ve Yüksekliği) Yüzde Değeri Olarak Ayarlama


149

Bir istediğini farz edelim TextBlockiçin onun Widtheşit 's Ana konteynerin Width(yani, yan yana gelen gerilme) ya da' s Ana konteynerin bir yüzdesi Widthiçinde bunu gerçekleştirmek nasıl, XAMLmutlak değerlerinin belirtmeden?

Üst Konteyner kapsayıcısı daha sonra genişletildiyse (' Widthartırıldı)' Alt Öğeleri de otomatik olarak genişletilecek şekilde bunu yapmak istiyorum . (temel olarak, HTML ve CSS'deki gibi)


Bu cevaba bir göz atın .
Jesper Fyhr Knudsen

Cwap'ın cevabını kullanın ve tb'yi germek için hizalandığı bir ızgara ayarına ekleyin.
Shimmy Weitzhandler

Yanıtlar:


90

Ana kapsayıcıyla aynı boyuta getirmenin yolu şu özniteliği kullanmaktır:

 <Textbox HorizontalAlignment="Stretch" ...

Bu, Metin Kutusu öğesini yatay olarak genişletecek ve tüm üst alanı yatay olarak dolduracaktır (aslında kullandığınız ana panele bağlıdır, ancak çoğu durumda çalışmalıdır).

Yüzdeler yalnızca ızgara hücre değerleriyle kullanılabilir, bu nedenle başka bir seçenek bir ızgara oluşturmak ve metin kutunuzu uygun yüzde olan hücrelerden birine koymaktır.


221

Kılavuzun satırlarında veya sütunlarında yüzde değerleri yapmak için metin kutularını kılavuzun içine yerleştirebilir ve metin kutularının üst hücrelerine otomatik olarak dolmasına izin verebilirsiniz (varsayılan olarak olduğu gibi). Misal:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="3*" />
    </Grid.ColumnDefinitions>

    <TextBox Grid.Column="0" />
    <TextBox Grid.Column="1" />
</Grid>

Bu, genişliği # 1 2/5 ve # 2 3/5 yapar.


7
Zaten denedim, ama bu hatayı alıyorum: '2 *' dize Uzunluk dönüştürülemez. '
Andreas Grech

6
Aslında * (Yıldız) küçük yıldızdır;) etymonline.com/index.php?term=asterisk
Pratik Deoghare

73
Annem bir yıldız olduğumu söylüyor
Denys Wessels

7
TextBox bir kılavuzda olsa bile bu çalışmaz. Genişlik, Çift, Nitelikli Çift (Çift değer ve ardından px, inç, cm veya pt) veya Otomatik olarak ayarlanabilir. Bkz. Msdn.microsoft.com/en-GB/library/…
Darren

2
Evet .. Bu aslında çok kötü bir cevap, ama tüm upvotes dayalı, sanırım birine yardımcı oldu (uzun zaman önceydi), bu yüzden silmedim.
cwap

58

Genellikle, senaryonuza uygun yerleşik bir yerleşim denetimi kullanırsınız (örneğin, üst öğeye göre ölçeklendirme istiyorsanız bir ızgarayı üst öğe olarak kullanın). Bunu rasgele bir üst öğe ile yapmak istiyorsanız, bunu yapmak için bir ValueConverter oluşturabilirsiniz, ancak muhtemelen istediğiniz kadar temiz olmayacaktır. Ancak, kesinlikle ihtiyacınız varsa, böyle bir şey yapabilirsiniz:

public class PercentageConverter : IValueConverter
{
    public object Convert(object value, 
        Type targetType, 
        object parameter, 
        System.Globalization.CultureInfo culture)
    {
        return System.Convert.ToDouble(value) * 
               System.Convert.ToDouble(parameter);
    }

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

Bir alt metin kutusunu üst tuvalinin genişliğinin% 10'unu elde etmek için böyle kullanılabilir:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <local:PercentageConverter x:Key="PercentageConverter"/>
    </Window.Resources>
    <Canvas x:Name="canvas">
        <TextBlock Text="Hello"
                   Background="Red" 
                   Width="{Binding 
                       Converter={StaticResource PercentageConverter}, 
                       ElementName=canvas, 
                       Path=ActualWidth, 
                       ConverterParameter=0.1}"/>
    </Canvas>
</Window>

Bu gerçekten harika, kodda nasıl yapabilirim (metin kutusunun genişliğini ayarlayın)?
Jeremy

9
CultureInfo.InvariantCultureÇifte dönüşüme eklemeyi düşünmelisiniz çünkü farklı parameterolarak kabul edilen stringkültürlerde ve decimal separatorbeklendiği gibi çalışmaz.
Flat Eric

33

'2 *' dizesi gibi bir hata alan herkes için Uzunluğa dönüştürülemez.

<Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" /><!--This will make any control in this column of grid take 2/5 of total width-->
        <ColumnDefinition Width="3*" /><!--This will make any control in this column of grid take 3/5 of total width-->
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition MinHeight="30" />
    </Grid.RowDefinitions>

    <TextBlock Grid.Column="0" Grid.Row="0">Your text block a:</TextBlock>
    <TextBlock Grid.Column="1" Grid.Row="0">Your text block b:</TextBlock>
</Grid>

Neden olmasın <RowDefinition Height="auto" />?
Ben

2
"auto" sadece kontrolün gerektirdiği kadar yer kaplar
Yama

Çok teşekkür ederim, bu en iyi cevap olmalı.
Mafii

Bu kesinlikle en iyi cevap.
Knut Valen

7

IValueConverter uygulaması kullanılabilir. IValueConverter'dan kalıtım alan dönüştürücü sınıfı value(yüzde) ve parameter(ebeveynin genişliği) gibi bazı parametreleri alır ve istenen genişlik değerini döndürür. XAML dosyasında, bileşenin genişliği istenen değerle şu değerle ayarlanır:

public class SizePercentageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter == null)
            return 0.7 * value.ToDouble();

        string[] split = parameter.ToString().Split('.');
        double parameterDouble = split[0].ToDouble() + split[1].ToDouble() / (Math.Pow(10, split[1].Length));
        return value.ToDouble() * parameterDouble;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Don't need to implement this
        return null;
    }
}

XAML:

<UserControl.Resources>
    <m:SizePercentageConverter x:Key="PercentageConverter" />
</UserControl.Resources>

<ScrollViewer VerticalScrollBarVisibility="Auto"
          HorizontalScrollBarVisibility="Disabled"
          Width="{Binding Converter={StaticResource PercentageConverter}, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualWidth}"
          Height="{Binding Converter={StaticResource PercentageConverter}, ConverterParameter=0.6, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualHeight}">
....
</ScrollViewer>

4

Xaml olmadığını biliyorum ama aynı şeyi metin kutusunun SizeChanged olayı ile yaptım:

private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
{
   TextBlock textBlock = sender as TextBlock;
   FrameworkElement element = textBlock.Parent as FrameworkElement;
   textBlock.Margin = new Thickness(0, 0, (element.ActualWidth / 100) * 20, 0);
}

Metin kutusu üst öğesinin% 80 büyüklüğünde (sağ kenar boşluğu% 20'dir) ve gerektiğinde uzar.


4

Göreceli boyutlandırma için iki yöntem kullanıyorum. Aradım bir sınıf var Relativeüç ekli özelliklere sahip To, WidthPercentve HeightPercentben bir unsur görsel ağacındaki bir element her yerde göreceli boyutunu olmak istiyorsanız yararlıdır ve dönüştürücü yaklaşımından daha az hacky hissediyor ki - her ne kadar sen misin, ne için çalışıyor kullanımı ile mutluyum.

Diğer yaklaşım ise daha kurnaz. Bir ekleme ViewBoxiçinizde göreceli boyutları istediğiniz yeri, o içeride, bir eklemek Gridbir eklerseniz Sonra genişliği 100'de TextBlockiçerde 10 genişlik ile, belli ki 100% 10'dur.

ViewBoxÖlçekleneceği Gridsayfadaki tek şey, o zaman, bu durumda onu verilmiş olursa olsun uzay göre Gridtam genişliği dışarı ölçekli edilecek ve etkin senin TextBlocksayfanın% 10 ölçeklenir.

Eğer bir yükseklik ayarlamazsanız Grid, içeriğine uyacak şekilde küçülür, böylece hepsi nispeten boyutlandırılır. İçeriğin çok uzun olmadığından emin olmanız gerekir; başka bir deyişle, verilen alana en boy oranını değiştirmeye başlar ViewBox, yüksekliği de ölçeklemeye başlar. Muhtemelen bu çalışabilirsiniz Stretcharasında UniformToFill.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.