简体   繁体   English

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

[英]How do I manage the width of controls through UserControl parameters?

In short, the goal is to propagate LabelWidth to its children in my UserControl class, PropertyView. 简而言之,目标是将LabelWidth传播到我的UserControl类PropertyView中的子级。 See this fragment: 看到这个片段:

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

ANSWER (credit to Athari for his part). 答案(Athari的信誉)。 To make it work, I needed two elements: In C#, a dependency property: 为了使其工作,我需要两个元素:在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)
                   );

In XAML, the following binding syntax: 在XAML中,以下绑定语法:

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

What didn't work (my original problem): 什么不起作用(我最初的问题):

See the ????? 见????? below in the XAML code. 在XAML代码下面。 I have NO IDEA what I can put in to make it so the SimpleControl will get a LabelWidth assigned, so that it will set its TextBlock's Width property. 我没有什么想法可以投入使用,因此SimpleControl将获得分配的LabelWidth,以便设置其TextBlock的Width属性。

I don't even care what approach is taken, it just needs to deal with the fact that PropertyView is bound to an XML object so it can display its properties, and LabelWidth needs to be a property the control-user sets that gets shoved down into the control. 我什至都不在乎采取什么方法,它只需要处理PropertyView绑定到XML对象以便可以显示其属性的事实,而LabelWidth需要是控件用户设置的属性,该属性已被缩减进入控制。 LabelWidth will vary depending on what object is being displayed, so it can't be global. 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#: 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();


      }          
}

I've searched extensively for a solution that deals with this combination of circumstances, tried many things without success (well, success for simpler situations, but not this), and I'm at a loss here. 我已经在广泛地寻找解决方案,以应对这种情况,尝试了很多没有成功的事情(好吧,对于简单的情况却没有成功),但我对此感到茫然。

Answer to edited question 回答已编辑的问题

Here's another go for your problem based on refined question. 这是根据提炼的问题来解决您的问题的另一种方法。 I'm still not 100% sure what you are trying to achieve but maybe the following points you to right direction, at least. 我仍然不是100%地确定您要实现的目标,但是至少以下几点可以使您指出正确的方向。

So there's a Window containing only UserControl. 因此,有一个仅包含UserControl的窗口。 This user control is bound to XML file and it has three label fields. 该用户控件绑定到XML文件,并且具有三个标签字段。 One shows node attritube and the following XML file content. 一个显示节点attritube和以下XML文件内容。 First label's width is bound to property in MainWindow and the other to static converter resource inside the UserControl. 第一个标签的宽度绑定到MainWindow中的属性,另一个标签绑定到UserControl中的静态转换器资源。

MainWindow XAML 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 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 codebehind XmlUserControl代码背后

using System.Windows.Controls;

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

NodeWidthConverter 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 sample data 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>

With this you'll get the following. 有了这个,您将获得以下内容。 Label has colored background to visualize the changing width properties. 标签具有彩色背景,以可视化变化的宽度属性。

未找到

Hope this helps! 希望这可以帮助!

So, you just need to bind SimpleControl.LabelWidth to PropertyView.LabelWidth ? 因此,您只需要将SimpleControl.LabelWidth绑定到PropertyView.LabelWidth It can be achieved this way: 可以通过以下方式实现:

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

PS Your dependency property is registered as "LabelWidth2" (typo?). PS您的依赖项属性已注册为"LabelWidth2""LabelWidth2" ?)。 And new PropertyMetadata(0.0) is redundant, as default(double) == 0.0 . new PropertyMetadata(0.0)是冗余的,因为default(double) == 0.0

Do you have a failed binding back to your StaticResources? 您绑定回StaticResources失败吗? Do you have values defined in the resources section? 您在资源部分中定义了值吗? Try something like this (note that I wrote this directly here (not in VS), it should be pretty much correct :) 尝试这样的事情(请注意,我是在这里直接写的(不是在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>

I would ask if you are really intending to go to StaticResources or whether you meant to bind to a property on a viewmodel or in the code behind of the view? 我想问一下您是否真的打算去StaticResources,还是要绑定到视图模型或视图背后的代码中的属性?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM