Устранение неисправности Binding Error 4 - PullRequest
0 голосов
/ 29 июня 2011

Я получаю следующие ошибки Binding в своем коде, и я не знаю, как их устранить. Привязки были сгенерированы VS. Я попытался добавить presentation.tracesources (что приведено в приведенном ниже коде), но получаю тот же вывод, что и раньше.

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='ClimateSolutions.SuperTB', AncestorLevel='1''. BindingExpression:Path=myName; DataItem=null; target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='ClimateSolutions.SuperTB', AncestorLevel='1''. BindingExpression:Path=isRequired; DataItem=null; target element is 'SuperTB' (Name='email'); target property is 'NoTarget' (type 'Object')

Вот мой XAML:

<TextBox x:Class="ClimateSolutions.SuperTB"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" Height="53" Width="296" FontSize="32"
         xmlns:local="clr-namespace:ClimateSolutions"
xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"

         HorizontalAlignment="Left" Name="Blarg">
<TextBox.Style>
    <Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Text" Value="">
                <Setter Property="Background">
                    <Setter.Value>
                        <VisualBrush Stretch="None">
                            <VisualBrush.Visual>
                                <TextBlock Foreground="Gray" FontSize="24" Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:SuperTB, AncestorLevel=1}, Path=myName, diagnostics:PresentationTraceSources.TraceLevel=High}">
                                </TextBlock>
                            </VisualBrush.Visual>
                        </VisualBrush>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <DataTrigger Binding="{Binding Path=isRequired, RelativeSource={RelativeSource FindAncestor, AncestorType=local:SuperTB, AncestorLevel=1}}" Value="False">
                <Setter Property="Text" Value="100" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</TextBox.Style>

и вот CS для SuperTB:

namespace ClimateSolutions
{
    /// <summary>
    /// Interaction logic for SuperTB.xaml
    /// </summary>
    public partial class SuperTB : TextBox, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String Property)
        {
            var anEvent = this.PropertyChanged;

            if (anEvent != null)
            {
                anEvent(this, new PropertyChangedEventArgs(Property));
            }
        }

        private String MyName = "Unicorns!";

        private static DependencyProperty myNameProperty = DependencyProperty.Register("myName", typeof(String), typeof(SuperTB));
        public String myName
        {
            get { return MyName; }
            set { MyName = value; NotifyPropertyChanged("myName"); }
        }

        DependencyProperty isRequiredProperty = DependencyProperty.Register("isRequired", typeof(Boolean), typeof(SuperTB));

        public Boolean isRequired
        {
            get { return (Boolean)GetValue(isRequiredProperty); }
            set { SetValue(isRequiredProperty, value); }
        }

        public SuperTB()
        {
            InitializeComponent();
            myName = "Unicorns!";
        }
    }
}

Ответы [ 2 ]

1 голос
/ 29 июня 2011

РЕДАКТИРОВАТЬ: я обновил код в соответствии с вашим комментарием.Подводя итог, можно сказать, что, поскольку это пользовательский элемент управления, вы меньше зависите от шаблона MVVM для построения логики вашего компонента (и, следовательно, используете код в своем компоненте), как только сам компонент отвечает этим требованиям (для сортировки, для настройки его свойств).быть настолько привязываемым, насколько это возможно).Например, в обновленном коде вы теперь можете связать свойство по умолчанию, но вы также можете представить экспонирующие свойства для установки цветов переднего плана, используемых для имени элемента управления отображением, когда значение отсутствует, и т. Д.


Я попробовал несколько вещей с вашим исходным кодом (включая решение, предоставленное J cooper), и ничего не получалось.Кажется, что с вашим кодом много проблем.

Мне удалось найти решение, сделав текстовое поле настраиваемым элементом управления.

Вот Generic.xaml (визуальное определениеваш элемент управления):

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Question_6514447">


<Style TargetType="{x:Type local:SuperTB2}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:SuperTB2}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <TextBox x:Name="PART_Input">
                        <TextBox.Style>
                            <Style TargetType="TextBox">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsRequired}" Value="False">
                                        <Setter Property="Text" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DefaultTextValue}" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBox.Style>
                    </TextBox>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</ResourceDictionary>

А вот код элемента управления:

 [TemplatePart(Name = "PART_Input")]
public class SuperTB2 : Control
{
    private TextBox PART_Input;
    static SuperTB2()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SuperTB2), new FrameworkPropertyMetadata(typeof(SuperTB2)));
    }

    public SuperTB2()
    {
        Loaded += SuperTb2Loaded;
    }
    public override void OnApplyTemplate()
    {
        PART_Input = GetTemplateChild("PART_Input") as TextBox;
        if (PART_Input != null)
        {


            PART_Input.GotFocus += PartInputGotFocus;
            PART_Input.LostFocus += PartInputLostFocus;
        }
    }

    void PartInputLostFocus(object sender, RoutedEventArgs e)
    {
        if (PART_Input.Text == string.Empty)
        {
            PART_Input.Text = Name;
            PART_Input.Foreground = new SolidColorBrush(Colors.Gray);
        }
    }

    void PartInputGotFocus(object sender, RoutedEventArgs e)
    {
        if (PART_Input.Text.Equals(Name))
        {
            PART_Input.Text = string.Empty;
            PART_Input.Foreground = new SolidColorBrush(Colors.Black);

        }
    }

    void SuperTb2Loaded(object sender, RoutedEventArgs e)
    {
        if (PART_Input.Text == string.Empty)
        {
            PART_Input.Text = Name;
            PART_Input.Foreground = new SolidColorBrush(Colors.Gray);
        }
    }

    private static DependencyProperty myNameProperty =
DependencyProperty.Register("MyName", typeof(string), typeof(SuperTB2), new PropertyMetadata("Unicorns !", NameChanged));

    private static void NameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {

    }

    public string MyName
    {
        get { return (string)GetValue(myNameProperty); }
        set { SetValue(myNameProperty, value); }
    }
    DependencyProperty isRequiredProperty =
        DependencyProperty.Register("IsRequired", typeof(bool), typeof(SuperTB2), new PropertyMetadata(false, IsReqChanged));

    private static void IsReqChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {

    }

    public bool IsRequired
    {
        get { return (bool)GetValue(isRequiredProperty); }
        set { SetValue(isRequiredProperty, value); }
    }



    public string DefaultTextValue
    {
        get { return (string)GetValue(DefaultTextValueProperty); }
        set { SetValue(DefaultTextValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for DefaultTextValue.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DefaultTextValueProperty =
        DependencyProperty.Register("DefaultTextValue", typeof(string), typeof(SuperTB2), new UIPropertyMetadata("100"));


}

И пример использования компонента:

<Grid>
    <StackPanel>
        <Question_6514447:SuperTB2 x:Name="FirstName" IsRequired="true" DefaultTextValue="200"/>
    </StackPanel>
</Grid>

С этим обновленным кодом, я думаю, вы можете достичь практически всех видов поведения, которые вам нужны!

Надеюсь, это поможет!

0 голосов
/ 29 июня 2011

Не используйте относительный источник в выражениях привязки. Относительный источник используется для доступа к элементам выше в дереве элементов. Кажется, вы использовали его с точки зрения наследования объектов.

<Trigger Property="Text" Value="">
    <Setter Property="Background">
        <Setter.Value>
            <VisualBrush Stretch="None">
                <VisualBrush.Visual>
                    <TextBlock Foreground="Gray" FontSize="24" Text="{Binding Path=myName, diagnostics:PresentationTraceSources.TraceLevel=High}">
                    </TextBlock>
                </VisualBrush.Visual>
            </VisualBrush>
        </Setter.Value>
    </Setter>
</Trigger>
<DataTrigger Binding="{Binding Path=isRequired}" Value="False">
    <Setter Property="Text" Value="100" />
</DataTrigger>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...