如何通过UserControl参数管理控件的宽度?

时间:2014-02-27 01:13:05

标签: c# .net wpf

简而言之,目标是在我的UserControl类PropertyView中将LabelWidth传播给它的子节点。看到这个片段:

     <TabItem.Header>Press</TabItem.Header>
    <TabItem.DataContext>
      <Binding XPath="press_information"/>
    </TabItem.DataContext>
    <W3V:PropertyView LabelWidth="200"></W3V:PropertyView>

答案(Athari表示赞同)。为了使它工作,我需要两个元素:在C#中,依赖属性:

      public double LabelWidth
      {            get { return (double)this.GetValue(LabelWidthProperty); }
        set { this.SetValue(LabelWidthProperty, value); }
      }
      public static readonly DependencyProperty LabelWidthProperty = 
          DependencyProperty.Register(
                   "LabelWidth", typeof(double), typeof(PropertyView), new PropertyMetadata(100.0)
                   );

在XAML中,使用以下绑定语法:

      <W3V:SimpleControl x:Name="simple"  Content="{Binding}" 
            LabelWidth="{Binding LabelWidth,
                         RelativeSource={RelativeSource AncestorType=W3V:PropertyView}}" />

什么行不通(我原来的问题):

看到?????下面是XAML代码。我没有IDEA我可以放入它,因此SimpleControl将分配LabelWidth,以便它将设置其TextBlock的Width属性。

我甚至不关心采用什么方法,它只需要处理PropertyView绑定到XML对象以便它可以显示其属性的事实,而LabelWidth需要是控件用户设置的属性。被推到控制之下。 LabelWidth将根据显示的对象而有所不同,因此它不能是全局的。

<UserControl x:Class="W3.Views.PropertyView" ... >

  <UserControl.Resources>
  </UserControl.Resources>
  <StackPanel Margin="2" CanVerticallyScroll="true">
    <Border Height="22">
    <TextBlock VerticalAlignment="Bottom"
    Text="{Binding XPath=@label}"
             FontSize="16" FontWeight="Bold" />
    </Border>
    <ItemsControl  ItemsSource="{Binding XPath=*}" Margin="20,0,0,0">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <W3V:SimpleControl x:Name="simple"  
                             Content="{Binding}" 
                             LabelWidth=?????? />
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>

  </StackPanel>

</UserControl>

C#:

public partial class PropertyView : UserControl
{
      public double LabelWidth
      {
        get { return (double)this.GetValue(LabelWidthProperty); }
        set { this.SetValue(LabelWidthProperty, value); }
      }
      public static readonly DependencyProperty LabelWidthProperty = 
          DependencyProperty.Register(
                   "LabelWidth2", typeof(double), typeof(PropertyView), new PropertyMetadata(0.0)
                   );
      public PropertyView()
      {
        InitializeComponent();


      }          
}

我已经广泛搜索了一个处理这种情况组合的解决方案,尝试了许多没有成功的事情(好的,简单情况的成功,但不是这个),我在这里不知所措。

3 个答案:

答案 0 :(得分:4)

回答编辑过的问题

这是基于精致问题的另一个问题。我仍然不能100%确定你想要实现的目标,但至少可能以下几点指向你正确的方向。

所以有一个只包含UserControl的Window。此用户控件绑定到XML文件,它有三个标签字段。一个显示节点attritube和以下XML文件内容。第一个标签的宽度绑定到MainWindow中的属性,另一个绑定到UserControl内的静态转换器资源。

MainWindow XAML

<Window x:Class="WpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:user="clr-namespace:WpfApplication"
        Title="MainWindow" Height="350" Width="600">
    <Grid>
        <user:XmlUserControl />
    </Grid>
</Window>

MainWindow Codebehind

using System;
using System.Windows;

namespace WpfApplication
{
    public partial class MainWindow : Window
    {
        readonly Random _random = new Random();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public double ControlWidth
        {
            get { return _random.Next(200, 600); }
        }
    }
}

XmlUserControl XAML

<UserControl x:Class="WpfApplication.XmlUserControl"
             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:local="clr-namespace:WpfApplication2"
             mc:Ignorable="d" 
             d:DesignHeight="350" d:DesignWidth="350">

    <StackPanel>
        <StackPanel.Resources>
            <XmlDataProvider x:Key="XmlData" XPath="Data/Items" Source="Items.xml" />
            <local:NodeWidthConverter x:Key="NodeWidthConverter" />
        </StackPanel.Resources>

    <ItemsControl>
        <ItemsControl.ItemsSource>
            <Binding Source="{StaticResource XmlData}" XPath="*"/>
        </ItemsControl.ItemsSource>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Label x:Name="Title" VerticalAlignment="Bottom" 
                           FontWeight="Bold" HorizontalAlignment="Left"
                           Content="{Binding XPath=@Title}" />
                        <Label Background="BurlyWood" HorizontalAlignment="Left" 
                               Content="{Binding}" Width="{Binding ControlWidth}" />
                        <Label Background="BlanchedAlmond" HorizontalAlignment="Left"
                               Content="{Binding}" Width="{Binding ElementName=Title, Converter={StaticResource NodeWidthConverter}}"/>
                    </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    </StackPanel>
</UserControl>

XmlUserControl代码隐藏

using System.Windows.Controls;

namespace WpfApplication
{
    public partial class XmlUserControl : UserControl
    {
        public XmlUserControl()
        {
            InitializeComponent();
        }
    }
}

<强> NodeWidthConverter

using System;
using System.Globalization;
using System.Windows.Data;

namespace WpfApplication2
{
    public class NodeWidthConverter : IValueConverter 
    {
        public static Random Random = new Random();

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return Random.Next(200, 600);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Items.xml示例数据

  <Data>
    <Items>
      <Item Title="Title 1">
        <Name>This is item name 1</Name>
        <Summary>Summary for item 1</Summary>
      </Item>
      <Item Title="Title 2">
        <Name>This is item name 2</Name>
        <Summary>Summary for item 2</Summary>
      </Item>
      <Item Title="Title 3">
        <Name>This is item name 3</Name>
        <Summary>Summary for item 3</Summary>
      </Item>
    </Items>
  </Data>

有了这个,你将获得以下内容。标签具有彩色背景,以显示更改的宽度属性。

notfound

希望这有帮助!

答案 1 :(得分:2)

那么,您只需将SimpleControl.LabelWidth绑定到PropertyView.LabelWidth?它可以通过这种方式实现:

<W3V:SimpleControl
    LabelWidth="{Binding Path=LabelWidth,
                     RelativeSource={RelativeSource AncestorType=PropertyView}}"

P.S。您的依赖项属性注册为"LabelWidth2"(错字?)。而new PropertyMetadata(0.0)是多余的,default(double) == 0.0

答案 2 :(得分:0)

您的StaticResources绑定失败了吗?您是否在资源部分中定义了值?尝试这样的事情(注意我在这里直接写了这个(不是在VS中),它应该是非常正确的:)

<UserControl ...>
    <UserControl.Resources>
        <System.Int x:Key="ContentWidth">100</System.Int> 
    </UserControl.Resources>



    <StackPanel Orientation="Horizontal" >
        <TextBlock Width="{StaticResource LabelWidth}" Text="test"/>
        <TextBox Width="{StaticResource ContentWidth}" />
    </StackPanel>
</UserControl>

我会问你是否真的打算去StaticResources,或者你是想绑定到viewmodel上的属性还是视图背后的代码?