كيفية تعيين أقصى عرض لعمود الشبكة اعتمادًا على حجم النافذة أو الشاشة في XAML

StackOverflow https://stackoverflow.com/questions/82323

  •  01-07-2019
  •  | 
  •  

سؤال

لدي شبكة مكونة من 3 أعمدة في نافذة بها GridSplitter في العمود الأول.أرغب في تعيين MaxWidth للعمود الأول على ثلث النافذة أو الصفحة الرئيسية Width (أو ActualWidth) وأفضل القيام بذلك في XAML إن أمكن.

هذه بعض نماذج XAML التي يمكنني اللعب بها في XamlPad (أو ما شابه) والتي توضح ما أفعله.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="Column1" Width="200"/>
            <ColumnDefinition x:Name="Column2" MinWidth="50" />
            <ColumnDefinition x:Name="Column3" Width="{ Binding ElementName=Column1, Path=Width }"/>
            </Grid.ColumnDefinitions>

        <Label Grid.Column="0" Background="Green" />
        <GridSplitter Grid.Column="0" Width="5" />
        <Label Grid.Column="1" Background="Yellow" />
        <Label Grid.Column="2" Background="Red" />
    </Grid>
</Page>

كما ترون ، يرتبط عرض العمود الأيمن بعرض العمود الأول ، لذلك عندما تنزلق العمود الأيسر باستخدام الفاصل ، فإن العمود الأيمن يفعل نفس الشيء :) إذا قمت بنزاع العمود الأيسر إلى اليمين ، في النهاية عليه في النهاية سوف تنزلق أكثر من نصف الصفحة/النافذة وعلى الجانب الأيمن من النافذة ، ودفع العمود 2 و 3 بعيدا.

أريد منع ذلك عن طريق ضبط MaxWidth للعمود 1 على ثلث عرض النافذة (أو شيء من هذا القبيل).يمكنني القيام بذلك في التعليمات البرمجية بسهولة تامة، ولكن كيف أفعل ذلك في "XAML فقط"؟

يحرر: اقترح David Schmitt استخدام SharedSizeGroup بدلاً من الربط، وهو اقتراح ممتاز.سيبدو نموذج التعليمات البرمجية الخاص بي كما يلي:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
        <Grid IsSharedSizeScope="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="Column1" SharedSizeGroup="ColWidth" Width="40"/>
                <ColumnDefinition x:Name="Column2" MinWidth="50" Width="*" />
                <ColumnDefinition x:Name="Column3" SharedSizeGroup="ColWidth"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Column="0" Background="Green" />
            <GridSplitter Grid.Column="0" Width="5" />
            <Label Grid.Column="1" Background="Yellow" />
            <Label Grid.Column="2" Background="Red" />
        </Grid>
</Page>
هل كانت مفيدة؟

المحلول

أعتقد أن نهج XAML فقط غير مباشر إلى حد ما، ولكن إليك طريقة للقيام بذلك.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:sys="clr-namespace:System;assembly=mscorlib"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

    <!-- This contains our real grid, and a reference grid for binding the layout-->
    <Grid x:Name="Container">

      <!-- hidden because it's behind the grid below -->
      <Grid x:Name="LayoutReference">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <!-- We need the border, because the column doesn't have an ActualWidth -->
        <Border x:Name="ReferenceBorder" 
                Background="Black" />
        <Border Background="White" Grid.Column="1" />
        <Border Background="Black" Grid.Column="2" />
      </Grid>

      <!-- I made this transparent, so we can see the reference -->
      <Grid Opacity="0.9">
          <Grid.ColumnDefinitions>
              <ColumnDefinition x:Name="Column1" 
                                MaxWidth="{Binding ElementName=ReferenceBorder,Path=ActualWidth}"/>
              <ColumnDefinition x:Name="Column2" 
                                MinWidth="50"  />
              <ColumnDefinition x:Name="Column3" 
                                Width="{ Binding ElementName=Column1, Path=Width }"/>
              </Grid.ColumnDefinitions>

          <Label Grid.Column="0" Background="Green"/>
          <GridSplitter Grid.Column="0" Width="5" />
          <Label Grid.Column="1" Background="Yellow" />
          <Label Grid.Column="2" Background="Red" />
      </Grid>
    </Grid>

</Page>

نصائح أخرى

كسول جدًا لدرجة أنني لا أستطيع كتابته بنفسي، ولكن يجب أن تكون قادرًا على استخدام محول رياضي والربط بعرض النوافذ الأم (إما بالاسم أو من خلال بحث أسلاف RelativeSource).

//I know I borrowed this from someone, sorry I forgot to add a comment from whom
public class ScaledValueConverter : IValueConverter
{
  public Object Convert(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
  {
     Double scalingFactor = 0;
     if (parameter != null)
     {
        Double.TryParse((String)(parameter), out scalingFactor);
     }

     if (scalingFactor == 0.0d)
     {
        return Double.NaN;
     }

     return (Double)value * scalingFactor;
  }

  public Object ConvertBack(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
  {
     throw new Exception("The method or operation is not implemented.");
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top