繁体   English   中英

在C#中的控件模板中访问控件

[英]Accessing a control within a control template in C#

WPF新手在这里。 我正在尝试建立一个表,希望在一周的每一天重复使用。 所以我将其移至控件模板。 这是XAML:

<ControlTemplate x:Key="defaultGridDesign" >
            <Grid HorizontalAlignment="Center" Margin="0,5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="80"/>
                    <ColumnDefinition Width="80"/>
                    <ColumnDefinition Width="200"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="200"/>
                    <ColumnDefinition Width="200"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="60"/>
                    <RowDefinition Height="60"/>
                </Grid.RowDefinitions>

                <Label x:Name="lblDayOfWeek" Style="{StaticResource BasicLabelLeft}" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Content="Monday"/>
                <Label x:Name="lblEmpty" Style="{StaticResource BasicLabelLeft}" Grid.Row="0" Grid.Column="1"/>
                <Label x:Name="lblPlanned" Style="{StaticResource BasicLabelLeft}" Content="Planned" Grid.Row="1" Grid.Column="1"/>
                <Label x:Name="lblProduced" Style="{StaticResource BasicLabelLeft}"  Content="Produced" Grid.Row="2" Grid.Column="1"/>
                <Label x:Name="lblPrevShift" Style="{StaticResource BasicLabelCenter}" Content="Previous Shift" Grid.Row="0" Grid.Column="2" />
                <Label x:Name="lblPlannedPrevShift" Style="{StaticResource BasicLabelLeft}" Content="n/a" Grid.Row="1" Grid.Column="2" />
                <Label x:Name="lblProducedPrevShift" Style="{StaticResource BasicLabelLeft}"  Content="n/a" Grid.Row="2" Grid.Column="2" />
                <Label x:Name="lbl1stHr" Style="{StaticResource BasicLabelCenter}" Content="01" Grid.Row="0" Grid.Column="3" />
                <Label x:Name="lbl2ndHr" Style="{StaticResource BasicLabelCenter}" Content="02" Grid.Row="0" Grid.Column="4" />
                <Label x:Name="lbl3rdHr" Style="{StaticResource BasicLabelCenter}" Content="03" Grid.Row="0" Grid.Column="5" />
                <Label x:Name="lbl4thHr" Style="{StaticResource BasicLabelCenter}" Content="04" Grid.Row="0" Grid.Column="6" />
                <Label x:Name="lbl5thHr" Style="{StaticResource BasicLabelCenter}" Content="05" Grid.Row="0" Grid.Column="7" />
                <Label x:Name="lbl6thHr" Style="{StaticResource BasicLabelCenter}" Content="06" Grid.Row="0" Grid.Column="8" />
                <Label x:Name="lbl7thHr" Style="{StaticResource BasicLabelCenter}" Content="07" Grid.Row="0" Grid.Column="9" />
                <Label x:Name="lbl8thHr" Style="{StaticResource BasicLabelCenter}" Content="08" Grid.Row="0" Grid.Column="10"/>
                <Label x:Name="lblTotal" Style="{StaticResource BasicLabelCenter}" Content="Total" Grid.Row="0" Grid.Column="11"/>
                <Label x:Name="lblNextShift" Style="{StaticResource BasicLabelCenter}" Content="Next Shift" Grid.Row="0" Grid.Column="12"/>
                <Label x:Name="lblPlannedTotal" Style="{StaticResource BasicLabelLeft}" Content="n/a" Grid.Row="1" Grid.Column="11"/>
                <Label x:Name="lblPlannedNextShift" Style="{StaticResource BasicLabelLeft}" Content="n/a" Grid.Row="1" Grid.Column="12"/>
                <Label x:Name="lblProducedTotal" Style="{StaticResource BasicLabelLeft}" Content="n/a" Grid.Row="2" Grid.Column="11"/>
                <Label x:Name="lblShiftOEE" Style="{StaticResource BasicLabelLeft}" Content="n/a" Grid.Row="2" Grid.Column="12"/>
                <StackPanel x:Name="stkPnlPlanned" Grid.Row="1" Grid.Column="3" Grid.ColumnSpan="8" Width="480"/>
                <StackPanel x:Name="stkPnlProduced" Grid.Row="2" Grid.Column="3" Grid.ColumnSpan="8" Width="480"/>
            </Grid>
        </ControlTemplate>

这就是我实例化它们的方式:

<StackPanel>
        <ContentControl Template="{StaticResource defaultGridDesign}" x:Name="ccTuesday"></ContentControl>
        <ContentControl Template="{StaticResource defaultGridDesign}" x:Name="ccWednesday" />
        <ContentControl Template="{StaticResource defaultGridDesign}" x:Name="ccThursday" />
        <ContentControl Template="{StaticResource defaultGridDesign}" x:Name="ccFriday" />
        <ContentControl Template="{StaticResource defaultGridDesign}" x:Name="ccSaturday" />
        <ContentControl Template="{StaticResource defaultGridDesign}" x:Name="ccMonday" />
    </StackPanel>

现在,当我想在控制模板中绑定标签时,碰到了砖墙。 我在网上找到的每个绑定示例都使用一个基本示例,但我还没有找到解决这种情况的示例。 我基本上想在第一行中设置小时数,在第一列中设置日期,但是最终我需要根据我从excel文件中读取的内容在堆栈面板上填充标签。 而且我希望堆叠面板的装订/填充将成为另一个整体。 每个表获得不同的信息。 每个小时,我需要更新每个。

我尝试了一下都没有用:

Label test = (Label) this.ccTuesday.Template.FindName("lblDayOfWeek", ccTuesday);

但是结果为空。

我一直在这里查看此讨论: https : //codereview.stackexchange.com/questions/44760/is-there-a-better-way-to-get-a-child

但是,访问一个标签确实确实有很多开销。

同样,我是新手,所以我不知道自己做得是否正确。 也许有更好,更优雅的方法可以做到这一点。 欢迎任何建议。

编辑1:
下面的答案有效,但是,当我尝试在视图和模型之间实现viewModel类时,如此链接http://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics -到高级级别#Level3:-添加操作和更改属性 ”界面

标签返回为空。

View类:

public partial class MainWindow : Window
    {
        private TableViewModel tableViewModelMonday = null;
        private TableViewModel tableViewModelTuesday = null;

        public MainWindow()
        {
            InitializeComponent();
            try
            {
                this.tableViewModelMonday = new TableViewModel("Monday");
                this.tableViewModelTuesday = new TableViewModel("Tuesday");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ccTuesday_Loaded(object sender, RoutedEventArgs e)
        {
            this.ccTuesday.DataContext = this.tableViewModelTuesday;
        }

        private void ccMonday_Loaded(object sender, RoutedEventArgs e)
        {
            this.ccMonday.DataContext = this.tableViewModelMonday;
        }

app.xaml,其中绑定是:

<Label x:Name="lblDayOfWeek" Style="{StaticResource BasicLabelLeft}" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Content="{Binding dayOfWeek}"/>

ViewModel类:

public class TableViewModel : INotifyPropertyChanged
    {
        private TableModel tableModel = null;

        public TableViewModel(string day)
        {
            tableModel = new TableModel(day);
        }

        public string lblDayOfWeek
        {
            get
            {
                return tableModel.dayOfWeek;
            }
            set
            {
                if (tableModel.dayOfWeek != value)
                {
                    tableModel.dayOfWeek = value;
                    this.OnNotifyPropertyChanged("dayOfWeek");
                }
            }
        }

        private void OnNotifyPropertyChanged(string msg)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(msg));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

    }

和模型类:

public class TableModel
    {
        private string _dayOfWeek;

        public string dayOfWeek
        {
            get
            {
                return this._dayOfWeek;
            }
            set
            {
                if (this._dayOfWeek != value)
                {
                    this._dayOfWeek = value;
                }
            }
        }

        public TableModel(string day)
        {
            this._dayOfWeek = day;
        }
    }

我想念什么?

您也可以通过UserControl实现可重用性。 无论哪种方式,要获得绑定功能,都可以定义一个Model类型,并将其分配给ContentControl(或UserControl)的DataContext属性。

首先,将标签绑定到ContentTemplate内:

<Label x:Name="lblDayOfWeek"
       Style="{StaticResource BasicLabelLeft}"
       Grid.Row="0"
       Grid.Column="0"
       Grid.RowSpan="3"
       Content="{Binding DayOfWeek}"/>

然后定义模型类:

public class Model : INotifyPropertyChanged {
    private DayOfWeek dayOfWeek;
    public DayOfWeek DayOfWeek {
        get {
            return this.dayOfWeek;
        }
        set {
            if (this.dayOfWeek != value) {
                this.dayOfWeek = value;
                this.OnNotifyPropertyChanged("DayOfWeek");
            }
        }
    }
    private void OnNotifyPropertyChanged(string name) {
        if (this.PropertyChanged != null) {
            this.PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

然后,您需要创建Model的实例并将其分配给DataContext:

public partial class MainWindow : Window {
    private ModelClass model = new ModelClass();
    public MainWindow() {
        InitializeComponent();
        this.customUserControl.DataContext = this.model;
    }

    private void button_Click(object sender, RoutedEventArgs e) {
        this.model.DayOfWeek = DayOfWeek.Sunday;
    }
}

现在,只要更改模型对象的DayOfWeek属性,ContentTemplate中的绑定标签就会更新。

关于将项目动态添加到StackPanel,可以考虑使用ItemsControl类。

只是让您知道, MVVM模式是用于设计WPF应用程序的最常见的设计模式。 按照此模式,您可以更好地使用强大的WPF功能(如绑定)。

暂无
暂无

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

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