2008-11-12 73 views
7

我试图将我的用户控件中的一个DependancyProperty绑定到的Width属性的Grid中。WPF绑定到网格列宽

我具有类似于此代码:

<Grid x:Name="MyGridName"> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition x:Name="TitleSection" Width="100" /> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 

    <Grid.RowDefinitions>...</Grid.RowDefinitions> 

    <GridSplitter x:Name="MyGridSplitter" Grid.Row="0" Grid.Column="0" ... /> 
</Grid> 

在一个单独的用户控件我有以下定义DependancyProperty

public static readonly DependencyProperty TitleWidthProperty = DependencyProperty.Register("TitleWidth", typeof(int), typeof(MyUserControl)); 

public int TitleWidth 
{ 
    get { return (int)base.GetValue(TitleWidthProperty); } 
    set { base.SetValue(TitleWidthProperty, value); } 
} 

我在代码中创建用户控件的实例,因此我有一个类似的绑定声明:

MyUserControl Cntrl = new MyUserControl(/* Construction Params */); 
BindingOperations.SetBinding(Cntrl , MyUserControl.AnotherProperty, new Binding { ElementName = "objZoomSlider", Path = new PropertyPath("Value"), Mode = BindingMode.OneWay }); 
BindingOperations.SetBinding(Cntrl , MyUserControl.TitleWidthProperty, new Binding { ElementName = "TitleSection", Path = new PropertyPath("ActualWidth"), Mode = BindingMode.OneWay }); 
/* Other operations on Cntrl */ 

第1装订定义的作品充满了想象,虽然这是绑定到一个实际的UIElement(在这种情况下是一个Slider),但绑定到“TitleSection”(这是在网格中定义的ColumnDefinition)失败。在代码中放置一个断点并在“TitleSection”上执行监视可返回预期的对象。

我开始怀疑x:Name'd ColumnDefinition不能绑定到。 任何人都可以建议我怎么能绑定到我的网格中第一列的变化宽度?

编辑#1 - 为了回答评论

数据绑定在这个意义上“失败”,与上引领者TitleWidth属性设置一个断点,并使用GridSplitter控制来调整第一列,断点不会被击中。另外,当DependancyProperty TitleWidth更改没有得到执行时,我预计会触发代码。

正在创建用户控件并将其添加到网格中的功能Window_Loaded函数中的Stackpanel。我期望在Usercontrols被构建的时候Grid已经被渲染了。当然,x:Named元素TitleSection是可视的,并且在构造/绑定发生之前,其值为100

编辑#2 - 可能与此有关?

我一直在嗅探Grid GridDefinition文档的MSDN页面,并且遇到了GridLength(),但我无法理解我如何在绑定表达式中使用它。我不能在绑定代码中使用关联的GridLengthConverter作为转换器,因为它不是从IValueConverter派生的。

我倾向于以某种方式绑定到网格对象的其中一个单元格的ActualWidth属性。它看起来不像绑定到列定义那么干净,但是目前我无法让它工作。

+0

不知道如何以及在什么时候创建usercontrol?网格是否显示? – Donnelle 2008-11-13 00:47:26

+0

您不能依赖在依赖属性的set/get中设置断点,因为它们永远不会被绑定引擎使用。内部依赖属性的设置使用SetValue(DependencyProperty,值) – 2008-11-13 08:51:37

回答

9

嗯,我已经得到了一个有点杂牌组装电脑工作的,我将如何为后人解释:

基本上我有在第一列排列,因此可以分离器右2列,多排栅如果其包含的内容需要更多空间,则由用户调整大小。为了使事情复杂化,我将用户控件以编程方式加载到一些行中,其中columnSpan为2,用于呈现目的(内容从一个单元格流入下一个单元格)。

当第一列被调整大小时,我需要在usercontrol中反映这一点。首先我尝试绑定到ColumnDefinition,但它确实不是在玩球。

我如何在第一列固定/ Kludged它

在备用电池我添加了一个<Label>带x:名称,使其访问。它在单元格中具有“拉伸”的默认属性并完全填充单元格。当列使用分离器调整大小时,它会被重新调整大小。绑定到标签的ActualWidth属性意味着对列大小的更改将正确传送到我的columnSpanned usercontrol中的DependancyProperty。

思考

显然,尽管有ColumnDefinition的ActualWidth属性时,它改变它不会出现在内部触发PropertyChanged事件(或这就是我最好的猜测)。这可能是一个错误,或通过设计,但对我来说,这意味着我不得不使用不太干净的解决方案。

3

您是否尝试过在xaml中设置绑定,以下内容应该适合您。

<ColumnDefinition 
    x:Name="TitleSection" 
    Width="{Binding 
       Path=TitleWidth, 
       RelativeSource={RelativeSource AncestorType=MyUserControl}}" 
    /> 

否则,看着您提供的绑定代码,它看起来周围的错误的方式对我来说,绑定的目标应该是网格列和源应该是您的依赖项属性。

用于上述XAML的等效代码是

BindingOperations.SetBinding(TitleSection, ColumnDefinition.WidthProperty, 
    new Binding() 
    { 
     RelativeSource= new RelativeSource(RelativeSourceMode.FindAncestor, typeof(MyUserControl),1), 
     Path = new PropertyPath("TitleWidth"), 
    }); 

在一个相关的说明,使用GridSplitter和装订宽度属性是mutally排斥。只要您使用分隔线调整列的大小,您的绑定将被替换为分隔符的值。

这与通过更新作为绑定目标的任何属性会遇到的情况类似。当您直接在代码中设置目标值时,您实际上将用您提供的值替换绑定对象。

2

ColumnDefinition.Width不是整数 - 它是一个GridLength。 您无法将GridLength直接绑定到整数,您需要一个转换器。

这也是为什么您无法将Control的Width属性(double)绑定到没有转换器的ColumnDefinition的Width属性(GridLength)的原因。