WPF - قم بتمرير قيمة عنصر تحكم واحد إلى محول لتعيين العرض على عنصر تحكم آخر

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

سؤال

أريد تعيين عرض TextBlock بناءً على عرض الحاوية الخاصة به، مطروحًا منه الهوامش المحددة في TextBlock.

هنا هو الكود الخاص بي

<TextBlock x:Name="txtStatusMessages" 
           Width="{Binding ElementName=LayoutRoot,Path=ActualWidth }"
                   TextWrapping="WrapWithOverflow" 
           Foreground="White" 
           Margin="5,5,5,5">This is a message
</TextBlock>

وهذا يعمل بشكل رائع باستثناء حقيقة أن TextBlock كبير جدًا بمقدار 10 وحدات بسبب تعيين الهوامش اليسرى واليمنى على 5.

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

أعرف كيفية استخدام المحولات، وحتى المحولات ذات المعلمات، وليس فقط معلمة مثل...Binding ElementName=LayoutRoot,Path=ActualWidth

على سبيل المثال، لا أستطيع القيام بهذا العمل...

Width="{Binding Converter={StaticResource PositionConverter},  
       ConverterParameter={Binding ElementName=LayoutRoot,Path=ActualWidth }}"

آمل أن أكون قد أوضحت ذلك بما فيه الكفاية وآمل أن تتمكن من المساعدة لأن Google لا تساعدني الليلة.

تيا!

دوغ

هل كانت مفيدة؟

المحلول

وكنت من المفترض أن استخدام جهاز التحكم الأخرى كمصدر، وليس المعلمة. المعلمة يجب أن تكون ثابتة وفي حالتك يمكن أن يكون -5.

وأنا لست بالقرب VS في الوقت الراهن لذلك بناء الجملة ربما غير دقيقة، ومع ذلك، هو شيء من هذا القبيل:

Width="{Binding ElementName=LayoutRoot, Path=ActualWidth,
Converter={StaticResource PositionConverter}, ConverterParameter=-5}"

و(المحول سيحصل -5 كسلسلة وسوف تضطر إلى تحويله إلى رقم قبل استخدامه.)

ومن تجربتي فمن الأفضل استخدام الاستدعاء OnXXXChanged من DependecyProperty XXX، وليس ربط عناصر التحكم داخل نفس السيطرة نافذة / جذر واحد إلى آخر. أحد أسباب ذلك هو أنك قد ترغب في ربط منهم إلى عنصر خارجي في وقت لاحق.

وأو بدلا من ذلك، استخدام multibinding:

<TextBlock>
    <TextBlock.Width>
        <MultiBinding Converter="{StaticResource yourConverter}">
            <MultiBinding.Bindings>
                <Binding /> <!-- Bind to parameter 1 here -->
                <Binding /> <!-- Bind to parameter 2 here -->
          </MultiBinding.Bindings>
        </MultiBinding>
    </TextBlock.Width>
</TextBlock>

وووالمحول الذي يحول المعلمتين إلى القيمة التي تريدها.

نصائح أخرى

وyes..multi يعمل من أجل لي ملزمة .. فعلا حاولت إرسال العنصر باعتباره convereterparameter، ولكن لعدم قبول. ولهذا السبب مررت عنصر كقيمة إلى فئة المحول.

وأدناه هو بلدي على سبيل المثال ..

<ListView ... >
<ListView.View>
<GridView>
    <GridViewColumn Header="xyz" >

        <GridViewColumn.Width>
            <MultiBinding Converter="{StaticResource GetWidthfromParentControl}">
                <MultiBinding.Bindings>
                    <Binding ElementName="lstNetwork" Path="ActualWidth"/>
                    <Binding ElementName="MyGridView"/>
                </MultiBinding.Bindings>
            </MultiBinding>
        </GridViewColumn.Width>
    ....
    </GridViewColumn>
    <GridViewColumn ...>
    ....
    </GridViewColumn>
</GridView>
</ListView.View>
</ListView>

في نافذة تغيير الحجم، لابد من حجمها أولا gridviewcolumn بلدي، وليس اثنين gridviewcolumns غيرها .. مررت Actualwidth من listview وأيضا مجموع الكائن gridview كعنصر .. إذا ذهبت رمز تحويل ...

class GetWidthfromParentControl : IMultiValueConverter
{
    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        GridView view = values[1] as GridView;
        GridViewColumnCollection collc = view.Columns;
        double actualWidths = collc[1].ActualWidth + collc[2].ActualWidth;
        return ((double)values[0] - actualWidths );
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

    #endregion
}

وهذا العمل بالنسبة لي ... :)

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

أولا XAML

<Window x:Class="WpfApplication1.Window2" ...
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window2" Height="300" Width="300">
    <Window.Resources>
        <local:WidthSansMarginConverter x:Key="widthConverter" />
    </Window.Resources>
    <Grid>
        <StackPanel x:Name="stack">
            <TextBlock x:Name="txtStatusMessages" 
                    Width="{Binding ElementName=stack,Path=ActualWidth, 
                        Converter={StaticResource widthConverter}}"
                    TextWrapping="WrapWithOverflow" 
                    Background="Aquamarine" 
                    Margin="5,5,5,5">
                This is a message
            </TextBlock>
            <TextBlock x:Name="txtWhatsWrongWithThis" 
                    TextWrapping="WrapWithOverflow" 
                    Background="Aquamarine" 
                    Margin="5,5,5,5">
                This is another message
            </TextBlock>
        </StackPanel>
    </Grid>
</Window>

التالي المحول.لدينا مشكلة هنا..منذ لا يمكن أن تكون ConverterParameter لأساليب التحويل قيمة ديناميكية لسبب ما.لذلك نحن نتسلل إلى هامش مربع النص عبر خاصية عامة للمحول التي قمنا بتعيينها في أداة Window.WidthSansMarginConverter.cs

public class WidthSansMarginConverter : IValueConverter
    {
        private Thickness m_Margin = new Thickness(0.0);

        public Thickness Margin
        {
            get { return m_Margin; }
            set { m_Margin = value; }
        }
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(double)) { return null; }

            double dParentWidth = Double.Parse(value.ToString());
            double dAdjustedWidth = dParentWidth-m_Margin.Left-m_Margin.Right;
            return (dAdjustedWidth < 0 ? 0 : dAdjustedWidth);
        }

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

        #endregion
    }

Window2.xaml.cs

        public Window2()
        {
            InitializeComponent();

            WidthSansMarginConverter obConverter = this.FindResource("widthConverter") as WidthSansMarginConverter;
            obConverter.Margin = txtStatusMessages.Margin;
        }

هث.شكرا على التمرين :)

إذا النص الخاص بك هو تابع مباشر من LayoutRoot، مجرد مجموعة من الخصائص التالية في مربع النص الخاص بك

HorizontalAlignment="Stretch"

ووفقا ل HTTP: //social.msdn.microsoft.com/Forums/en-US/wpf/thread/7298ceb5-bf56-47aa-a161-5dd99189408b ، يمكنك إضافة خاصية التبعية لتحويل عهدك إذا مشتق تحويل الخاص بك من DependencyObject.

في هذه الحالة هل يمكن حتى استخدام ربط البيانات لتمرير القيم إلى هذه الخصائص حيث يمكنك تحديد تحويل (في القاموس الموارد) في XAML.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top