سؤال

أرغب في ضبط حدود حدود UserControl باستخدام 4 مربعات نصية ، لكن لا يمكنني تشغيلها.

رمز XAML الذي يوضح المشكلة (هناك حاجة فقط إلى هذا الرمز بالاقتران مع المحول):

<Window 
    x:Class="BorderThicknessBindingTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:BorderThicknessBindingTest="clr-namespace:BorderThicknessBindingTest" 
    Height="300" Width="500">
    <Window.Resources>
        <BorderThicknessBindingTest:ThicknessConverter x:Key="ThicknessConverter"/>
    </Window.Resources>

    <Grid Margin="10">
        <Border 
            x:Name="MyBorder"
            BorderBrush="Black" 
            Background="AliceBlue"
            BorderThickness="3"/>
        <TextBox 
            HorizontalAlignment="Center" VerticalAlignment="Center"
            Text="{Binding Path=BorderThickness.Left, ElementName=MyBorder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ThicknessConverter}}"/>
    </Grid>
</Window>

هناك حاجة إلى محول لتحليل إدخال السلسلة في مربع النص:

public class ThicknessConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value; // don't need to do anything here
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double d;
        Double.TryParse((string) value, out d); // Thickness.Left doesn't take a string
        return d;
    }
}

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

هل يعرف أي شخص كيفية القيام بذلك وإصلاح هذا؟

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

المحلول

لا يتم تحديث العنصر على الشاشة ديناميكيًا لأنه لم يخبر أي شيء العنصر في حقل ما فيه BorderThickness لقد تغيرت الممتلكات. تحتاج إلى إخطار العنصر بأنه BorderThickness لقد تغير ، والذي يمكنك القيام به فقط من خلال تعيين خاصية التبعية مباشرة على قيمة جديدة - على سبيل المثال ، من خلال جعلها هدفًا لربط كائن يغير الإخطار.

إنه شيء من الألم لجعل نموذج عرض لهذا ، ولكن بمجرد القيام بذلك ، يتم ذلك.

النافذة:

<Window x:Class="ThicknessDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=System" xmlns:ThicknessDemo="clr-namespace:ThicknessDemo" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ThicknessDemo:ThicknessViewModel x:Key="thickness" />
    </Window.Resources>
        <DockPanel DataContext="{StaticResource thickness}">
            <Border DockPanel.Dock="Top"
                    Width="100"
                    Height="50"
                    Margin="5"
                    BorderBrush="Blue"
                    BorderThickness="{Binding Thickness}" />
            <TextBox DockPanel.Dock="Top"
                        Text="{Binding Left, Mode=TwoWay}" />
            <TextBox DockPanel.Dock="Top"
                        Text="{Binding Right, Mode=TwoWay}" />
            <TextBox DockPanel.Dock="Top"
                        Text="{Binding Top, Mode=TwoWay}" />
            <TextBox DockPanel.Dock="Top"
                        Text="{Binding Bottom, Mode=TwoWay}" />
            <TextBlock DockPanel.Dock="Top" />
        </DockPanel>
</Window>

نموذج العرض:

public class ThicknessViewModel : INotifyPropertyChanged
{
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler h = PropertyChanged;
        if (h != null)
        {
            h(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public ThicknessViewModel()
    {
        _Thickness = new Thickness(1, 1, 1, 1);
    }

    private Thickness _Thickness;

    public Thickness Thickness { get { return _Thickness; } set { _Thickness = value;} }

    public double Left
    {
        get { return _Thickness.Left; }
        set
        {
            _Thickness.Left = value;
            OnPropertyChanged("Thickness");
        }
    }

    public double Right
    {
        get { return _Thickness.Right; }
        set
        {
            _Thickness.Right = value;
            OnPropertyChanged("Thickness");
        }
    }

    public double Top
    {
        get { return _Thickness.Top; }
        set
        {
            _Thickness.Top = value;
            OnPropertyChanged("Thickness");
        }
    }

    public double Bottom
    {
        get { return _Thickness.Bottom; }
        set
        {
            _Thickness.Bottom = value;
            OnPropertyChanged("Thickness");
        }
    }
}

نصائح أخرى

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

http://10rem.net/blog/2010/05/08/breaking-apart-the-margin-property-in-xaml-better-binding

اتضح أن أبسط الحلول بالنسبة لي هو الاستماع فقط إلى حدث Textchanged من مربع النص ، واستبدال الحدود في الكود وراء.

mainwindow.xaml:

<Window 
    x:Class="BorderThicknessBindingTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:BorderThicknessBindingTest="clr-namespace:BorderThicknessBindingTest" 
    Height="300" Width="500">

    <Grid Margin="10">
        <Border 
            x:Name="MyBorder"
            BorderBrush="Black" 
            Background="AliceBlue"
            BorderThickness="3"/>
        <TextBox 
            x:Name="MyTextBox"
            HorizontalAlignment="Center" VerticalAlignment="Center"
            Text="{Binding Path=BorderThickness.Left, ElementName=MyBorder, Mode=OneWay}"/>
    </Grid>
</Window>

mainwindow.xaml.cs ، في المُنشئ:

MyTextBox.TextChanged += (sender, e) =>
{
    double d;
    if (!double.TryParse(MyTextBox.Text, out d)) return;
    var t = MyBorder.BorderThickness;
    t.Left = d;
    MyBorder.BorderThickness = t;
};

هذا يعمل الآن بالنسبة لي ، حل روبرت روسني أفضل.

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