如何防止这段代码重复10次?

时间:2015-06-20 16:31:31

标签: c# wpf xaml

我在XAML中使用了下面的10个网格,每次使用其他绑定源。 我是否必须重复(复制/粘贴)此代码10次或者有更好的方法吗? (模板?)

<Grid>                               
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
     </Grid.RowDefinitions>
     <TextBox
           Style="{StaticResource TBGrid}"
           Grid.Column="0"
           Grid.Row="0"
           Text="{Binding ...}" />
     <Label
          Style="{StaticResource TBLabel}"
          Grid.Column="1"
          Grid.Row="0"
          Content="{Binding....}" />
</Grid>

现在我有这个代码,在评论者的帮助下,似乎有效:

using System.Windows;
using System.Windows.Controls;

namespace MVVMCable
{
    /// <summary>
    /// Interaction logic for ArrowLabel.xaml
    /// </summary>
    public partial class ArrowLabel : UserControl
    {
        public ArrowLabel()
        {
            InitializeComponent();
            this.DataContext = this;  //  <==== this must be added, seemingly.
        }
        public static readonly DependencyProperty TextBoxTextProperty = DependencyProperty.Register
            (
                "TextBoxText",
                typeof(string),
                typeof(ArrowLabel),
                new PropertyMetadata("")
            );

        public string TextBoxText
        {
            get { return this.GetValue(TextBoxTextProperty) as string; }
            set { this.SetValue(TextBoxTextProperty, value); }
        }

        public static readonly DependencyProperty LabelTextProperty = DependencyProperty.Register
            (
                "LabelText",
                typeof(string),
                typeof(ArrowLabel),
                new PropertyMetadata("")
            );

        public string LabelText
        {
            get { return this.GetValue(LabelTextProperty) as string; }
            set { this.SetValue(LabelTextProperty, value); }
        }
    }
}

XAML:

<UserControl
    x:Class="MVVMCable.ArrowLabel"
    x:Name="MyArrowLabel"
    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"
    mc:Ignorable="d"
    d:DesignHeight="137.8"
    d:DesignWidth="279.2">
    <Grid
        Width="70"
        Height="15">
        <Grid.ColumnDefinitions>
            <ColumnDefinition
                Width="40"/>
            <ColumnDefinition
                Width="30"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition
                Height="14" />
        </Grid.RowDefinitions>
        <TextBox
            Height="20"
            Grid.Column="0"
            Grid.Row="0"
            IsEnabled="False"
            HorizontalContentAlignment="Right"
            Width="30"
            Text="{Binding ElementName=MyArrowLabel, Path=TextBoxText}"/>
        <Label
            Height="auto"
            Grid.Column="1"
            Grid.Row="0"
            HorizontalContentAlignment="Left"
            Width="auto"
            Content="{Binding ElementName=MyArrowLabel, Path=LabelText}"/>

    </Grid>
</UserControl>

我在我的应用程序中使用它:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:c="clr-namespace:MVVMCable"
    xmlns:oxy="http://oxyplot.org/wpf"
    xmlns:shapes="clr-namespace:MVVMCable.Views"
    xmlns:core="clr-namespace:System;assembly=mscorlib"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    x:Class="MVVMCable.MainWindow"
    .......
     <c:ArrowLabel
         Canvas.Left="10"
         Canvas.Top="6"
         TextBoxText="{Binding Cable.RHVc}"  <== error here and
         LabelText="{Binding Units[X].Display}" />   <== here

错误文字是:

错误2无法识别或无法访问成员“LabelText”。

在添加this.DataContext = this;之后,事情似乎有效。

3 个答案:

答案 0 :(得分:4)

因为每个DataContext会有不同,我建议您使用自定义UserControl

例如:

UserControl本身会有重复的XAML

<UserControl
    x:Class="SpecialUserControl"
    x:Name="MyUserControl"
    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"
    mc:Ignorable="d">
    <Grid>                               
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
         </Grid.RowDefinitions>
         <TextBox
               Style="{StaticResource TBGrid}"
               Grid.Column="0"
               Grid.Row="0"
               Text="{Binding ElementName=MyUserControl, Path=TextBoxText}" />
         <Label
              Style="{StaticResource TBLabel}"
              Grid.Column="1"
              Grid.Row="0"
              Content="{Binding ElementName=MyUserControl, Path=LabelText}" />
    </Grid>
</UserControl>

UserControl后面的代码将有两个DependencyProperties

public static readonly DependencyProperty TextBoxTextProperty = 
    DependencyProperty.Register
    (
        "TextBoxText", 
        typeof(string), 
        typeof(SpecialUserControl),
        new PropertyMetadata("")
    );

public string TextBoxText
{
    get { return this.GetValue(TextBoxTextProperty) as string; }
    set { this.SetValue(TextBoxTextProperty, value); }
}

public static readonly DependencyProperty LabelTextProperty = 
    DependencyProperty.Register
    (
        "LabelText", 
        typeof(string), 
        typeof(SpecialUserControl),
        new PropertyMetadata("")
    );

public string LabelText
{
    get { return this.GetValue(LabelTextProperty) as string; }
    set { this.SetValue(LabelTextProperty, value); }
}

如果您注意到,UserControl XAML实际上绑定了DependencyPropertiesTextBox控件的这些Label

现在使用,您只需使用定义的DependencyProperties绑定到您想要的任何内容:

<namespace:SpecialUserControl 
    TextBoxText="{Binding ThisIsABinding}" 
    LabelText="{Binding ThisIsAnotherBinding}"/>

答案 1 :(得分:0)

如果绑定可以在大多数情况下是标准化的,并且您只能切换上下文,那么您应该创建一个UserControl,将您的内容放在那里。并在需要的地方使用它而不是重复代码,只需更改它们绑定的DataContext。

答案 2 :(得分:0)

您可以通过依赖项属性创建自定义字段控件。在此字段控件中,您可以将标签和文本框功能组合在一起。然后你可以把控制权放在stackpanel中。因此,它将删除冗余代码。