开发者

WPF binding does not work

开发者 https://www.devze.com 2023-03-19 12:46 出处:网络
I have some textbox in my form and they are defined as follow: <TextBox Grid.Column=\"1\" Grid.Row=\"0\" x:Name=\"titl开发者_高级运维eTextBox\" Text=\"{Binding Path=Title}\"IsEnabled=\"{Binding Pa

I have some textbox in my form and they are defined as follow:

<TextBox Grid.Column="1" Grid.Row="0" x:Name="titl开发者_高级运维eTextBox" Text="{Binding Path=Title}"  IsEnabled="{Binding Path=IsEditing, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ec:DetailDataControl}}}"/>

but I'm getting this error during run time:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='MyProject.Controls.DetailDataControl', AncestorLevel='1''. BindingExpression:Path=IsEditing; DataItem=null; target element is 'TextBox' (Name='titleTextBox'); target property is 'IsEnabled' (type 'Boolean')

Why this is happening and how can I solve it?

Update1

IsEditting is defined as follow:

public static readonly DependencyProperty IsEditingProperty = DependencyProperty.Register(
            "IsEditing", typeof(Boolean), typeof(DetailDataControl), new PropertyMetadata(false));

public Boolean IsEditing
{
    get { return (Boolean)GetValue(IsEditingProperty); }
    set { SetValue(IsEditingProperty, value); }
}

Update2

the XAMl structure is as follow: (I removed some parst that is not relevent)

<ad:DocumentContent x:Class="MyProject.Controls.DetailDataControl"
         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"
         xmlns:ec="clr-namespace:MyProject.Controls"
         xmlns:ecc="clr-namespace:MyProject.Classes.Converters"
         xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
         mc:Ignorable="d"
         d:DesignHeight="300" d:DesignWidth="300">



<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition  Height="*"/>
    </Grid.RowDefinitions>
    <WrapPanel HorizontalAlignment="Right"  VerticalAlignment="Stretch" Grid.Row="0" >
        <Button Content="Edit" HorizontalAlignment="Right"  Name="editButton1" VerticalAlignment="Stretch" Click="editButton1_Click" />
    </WrapPanel>

    <Grid x:Name="pDataGrid" Margin="10,10,10,10" Grid.Row="1">
        <Grid.Resources>
            <ecc:InvertBooleanConverter  x:Key="boolConvert"/>
            <Style x:Key="BaseStyle" TargetType="Control">
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="VerticalAlignment" Value="Stretch"/>
                <Setter Property="FontFamily" Value="Arial"/>
                <Setter Property="FontSize" Value="12" />

            </Style>

            <Style TargetType="Label" BasedOn="{StaticResource BaseStyle}" >
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="VerticalAlignment" Value="Stretch"/>
                <Setter Property="Foreground" Value="Blue"/>
            </Style>
            <Style TargetType="TextBox" BasedOn="{StaticResource BaseStyle}">
            </Style>
            <Style TargetType="DatePicker" BasedOn="{StaticResource BaseStyle}" >
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="VerticalAlignment" Value="Stretch"/>
                <Setter Property="IsHitTestVisible"  Value="{Binding Path=IsEditing, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ec:DetailDataControl}}}" />

            </Style>
            <Style TargetType="ComboBox" BasedOn="{StaticResource BaseStyle}">
                <Setter Property="IsEnabled" Value="{Binding Path=IsEditing, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ec:DetailDataControl}}}" />
            </Style>
            <Style TargetType="Button" BasedOn="{StaticResource BaseStyle}">
                <Setter Property="Width" Value="75" />
            </Style>
            <Style TargetType="RowDefinition"   >
                <Setter Property="Height" Value="30" />
                <Setter Property="SharedSizeGroup" Value="RowzSize"/>
            </Style>
            <Style x:Key="LabelColumnStyle" TargetType="ColumnDefinition"  >
                <Setter Property="Width" Value="*" />
                <Setter Property="SharedSizeGroup" Value="LabelColumnszSize"/>
            </Style>
            <Style x:Key="TextColumnStyle" TargetType="ColumnDefinition"   >
                <Setter Property="Width" Value="3*" />

            </Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Style="{StaticResource LabelColumnStyle}"/>
            <ColumnDefinition Style="{StaticResource TextColumnStyle}"/>


        </Grid.ColumnDefinitions>

        <Label Content="Title" Grid.Column="0" Grid.Row="0" />
        <TextBox Grid.Column="1" Grid.Row="0" x:Name="titleTextBox" Text="{Binding Path=Title}"  IsEnabled="{Binding Path=IsEditing, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ec:DetailDataControl}}}"/>

      </Grid>
    <TabControl Grid.Row="2" HorizontalAlignment="Stretch"  Name="tabControl1" VerticalAlignment="Stretch" >
        <TabItem Header="Address" Name="addresTabItem">
            <DataGrid  Name="addressDataGrid"  AutoGenerateColumns="False" ItemsSource="{Binding}" IsReadOnly="True">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Path='Order'}" Header="Order" Width="*" />
                    <DataGridTextColumn Binding="{Binding Path='Address1'}" Header="Address1"   Width="3*" />
                    <DataGridTextColumn Binding="{Binding Path='Address2'}" Header="Address2" Width="3*" />
                    <DataGridTextColumn Binding="{Binding Path='Postcode'}" Header="Postcode" Width="*" />
                    <DataGridTextColumn Binding="{Binding Path='TelNo'}" Header="TelNo" Width="*" />
                    <DataGridTextColumn Binding="{Binding Path='MovedToAddressDate', StringFormat={}\{0:dd/MM/yyyy\}}" Header="Moved Date" Width="*" />
                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Button" Tag="{Binding Path=ID}"  Name="editAddressButton" Click="editAddressButton_Click" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>

            </DataGrid>
        </TabItem>


    </TabControl>

</Grid>


If you are trying to do some thing like

<ec:DetailDataControl></ec:DetailDataControl>

        <TextBox Grid.Column="1" Grid.Row="0" x:Name="titleTextBox" Text="{Binding Path=Title}"  IsEnabled="{Binding Path=IsEditing, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ec:DetailDataControl}}}" Width="100"/>

It will definitely gives

Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='WpfApplication1.DetailDataControl', AncestorLevel='1''. BindingExpression:Path=IsEditing; DataItem=null; target element is 'TextBox' (Name='titleTextBox'); target property is 'IsEnabled' (type 'Boolean')

Because Relative source find ancestor will always search for parent of type ec:DetailDataControl. it will never consider sibling elements (elements in the same level) Find ancestor will look for parent of type ec:DetailDataControl if it fails to find the parent of type ec:DetailDataControl then it will look for next level parent like that it will search until it reaches top level parent but it never consider siblings.

Here is one simple solution to your problem.

<ec:DetailDataControl x:Name="ddc"></ec:DetailDataControl>

        <TextBox Grid.Column="1" Grid.Row="0" x:Name="titleTextBox" Text="{Binding Path=Title}"  IsEnabled="{Binding Path=IsEditing, ElementName=ddc}" Width="100"/>
0

精彩评论

暂无评论...
验证码 换一张
取 消