none
WPF,绑定覆盖,这是闹哪样啊? RRS feed

  • 问题

  • 一个自定义控件:

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPF3">
        <Style TargetType="{x:Type local:CustomControl1}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                        <Border Background="#FFEEF5E9" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                            <ContentPresenter Content="{TemplateBinding Content}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    public class CustomControl1 : ContentControl
    {
        static CustomControl1()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
        }
        public CustomControl1()
        {
            Height = 50;
            Binding binding = new Binding("Height");
            binding.RelativeSource = RelativeSource.Self;
            binding.Converter = new MyConverter();
            SetBinding(ContentProperty, binding);
            bindingexpression = BindingOperations.GetBindingExpression(this, ContentProperty);
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            bindingexpression = BindingOperations.GetBindingExpression(this, WidthProperty);
        }
        BindingExpression bindingexpression;
    }
    class MyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value.ToString();
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    <Window x:Class="WPF3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WPF3"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:MyConverter x:Key="MyConverter"/>
        </Window.Resources>
        <Grid Name="grid1">
            <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="90,220,0,0" VerticalAlignment="Top" Width="76"/>
            <Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Margin="250,219,0,0" VerticalAlignment="Top" Width="74"/>
            <local:CustomControl1 FontSize="40" Width="100" Content="{Binding ElementName=button, Path=Width, Converter={StaticResource MyConverter}}"/>
        </Grid>
    </Window>

    在上面的代码中,自定义控件CustomControl1的构造函数中创建了将Content绑定到自身的高度属性上显示,使用了值转换器MyConverter。在窗体中,一个CustomControl1将Content绑定到button的Width上,启动运行,结果显示的是76,这个结果似乎没有值得怀疑,在窗体中设置的数据绑定覆盖了在构造函数中设置的数据绑定。

    不过现在,其它代码不变,只是把窗体修作如下修改:

    <Window x:Class="WPF3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WPF3"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:MyConverter x:Key="MyConverter"/>
        </Window.Resources>
        <Grid>
            <Button Content="熊俊" FontSize="40" >
                <Button.ContentTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <TextBlock Text="我爱"/>
                            <local:CustomControl1 Grid.Row="1" Content="{Binding Converter={StaticResource MyConverter}}"/>                            
                        </Grid>
                    </DataTemplate>
                </Button.ContentTemplate>
            </Button>
        </Grid>
    </Window>

    在窗体代码中,设置了Button的数据模板,在数据模板中使用了CustomControl1,并将其Content绑定到Button内容上,启动运行,最终结果却是下面的显示:

    结果显示中的50就是在CustomControl1的构造函数中设置的高度值,而不是"熊俊",也就是说CustomControl1使用的仍然是构造函数中创建的绑定,而没有使用数据模板中的Binding,那么,为什么在数据模板中设置的绑定,没有覆盖构造函数中的绑定呢?

    谢谢!!




    2015年11月23日 0:18

全部回复

  • 绑定是需要指定数据上下文的,你的第一个例子给它指定了ElementName,所以你的CustomControl的数据上下文就是ElementName所对应的控件,而你第二个例子,CustomControl包含在外层控件里,当你使用binding时,他会从自身开始找DataContext,当找到最外层还没有找到时,就是把自己当作DataContext,所以我觉得你获得的结果没有任何问题。
    2015年11月24日 5:48
  • 绑定是需要指定数据上下文的,你的第一个例子给它指定了ElementName,所以你的CustomControl的数据上下文就是ElementName所对应的控件,而你第二个例子,CustomControl包含在外层控件里,当你使用binding时,他会从自身开始找DataContext,当找到最外层还没有找到时,就是把自己当作DataContext,所以我觉得你获得的结果没有任何问题。

    阁下的解释不太正确哦。按照你说的,我又将窗体代码作了一点小修改:

    <Window x:Class="WPF3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WPF3"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <local:MyConverter x:Key="MyConverter"/>
        </Window.Resources>
        <Grid>
            <Button Content="熊俊" FontSize="40" >
                <Button.ContentTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <TextBlock Name="aaa" Text="我爱"/>
                            <local:CustomControl1 Grid.Row="1" Content="{Binding Converter={StaticResource MyConverter}}"/>
                            <local:CustomControl1 Grid.Row="2" Content="{Binding ElementName=aaa, Path=Text, Converter={StaticResource MyConverter}}"/>
                        </Grid>
                    </DataTemplate>
                </Button.ContentTemplate>
            </Button>
        </Grid>
    </Window>

    添加了一个CustomControl1,为其绑定添加了ElementName,绑定到TextBlock的Text属性,但是结果显示也并没有显示TextBlock的Text。如下图:


    2015年11月24日 9:23
  • 你可以上传你的代码吗?我照着你的代码建了个项目,发现运行不起来。
    • 已编辑 messizhu 2015年11月25日 5:11
    2015年11月25日 5:11
  • 你可以上传你的代码吗?我照着你的代码建了个项目,发现运行不起来。

    我用的VS 2015

    好像不能上传文件的哦

    请到云盘下载:http://url.cn/Zlojxw

    2015年11月25日 14:19
  • 你给自定义控件在构造函数中设置了默认值,会覆盖xaml上的绑定。
    2015年11月27日 3:28
  • 你给自定义控件在构造函数中设置了默认值,会覆盖xaml上的绑定。

    构造函数中设置的值能覆盖XAML中设置的值?构造函数比XAML数据获取后执行吗?

    况且我的问题有2段代码,第一段代码就说明是是XAML中的绑定覆盖了构造函数中设置的绑定。


    2015年11月27日 10:56
  • 哪位高手能解答下吗????????
    2015年12月10日 13:42