简体   繁体   English

引用添加到StackPanel的WPF控件

[英]Reference a WPF Control added to a StackPanel

This is a problem I've been trying to solve for a couple of days but I'm yet to find a good solution. 我已经尝试解决了几天这个问题,但是我还没有找到一个好的解决方案。

I have a main WPF window which contains a StackPanel. 我有一个主要的WPF窗口,其中包含一个StackPanel。 I also have a class called "MessageManagement" which contains a List of custom WPF controls called "MessagePreview". 我还有一个名为“ MessageManagement”的类,其中包含一个名为“ MessagePreview”的自定义WPF控件的列表。

MessagePreview 留言预览

<UserControl x:Class="FinalYearProject.MessagePreview"
         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="58" d:DesignWidth="254" Background="White" BorderThickness="1" BorderBrush="#FF320000">
<Grid Name="grid1">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50" MaxWidth="50" MinWidth="50" />
        <ColumnDefinition Width="197*" MinWidth="20" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="1" Name="grid2">
        <Grid.RowDefinitions>
            <RowDefinition Height="31*" />
            <RowDefinition Height="34*" />
            <RowDefinition Height="33*" />
        </Grid.RowDefinitions>
        <Label Content="-ERROR-" Height="28" HorizontalAlignment="Left" Margin="2,1,0,0" Name="senderLabel" VerticalAlignment="Top" Foreground="#FF0000B4" Grid.RowSpan="2" />
        <Label Content="-ERROR-" Height="33" HorizontalAlignment="Left" Name="previewLabel" VerticalAlignment="Top" Margin="-1,17,0,0" Grid.RowSpan="3" />
        <Label Content="-Error-" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="0,16,6,0" Name="timeLabel" VerticalAlignment="Top" Grid.RowSpan="2" Width="196" />
    </Grid>
    <Grid Name="grid3">
        <Grid.RowDefinitions>
            <RowDefinition Height="29*" />
            <RowDefinition Height="27*" />
        </Grid.RowDefinitions>
        <Image Height="38" HorizontalAlignment="Center" Margin="3,0,6,20" Name="image1" Stretch="Fill" VerticalAlignment="Bottom" Width="41" Source="/FinalYearProject;component/Images/twitter-bird-light-bgs.png" Grid.RowSpan="2" />
        <CheckBox Height="16" Margin="15,0,22,6" Name="checkBox" VerticalAlignment="Bottom" Grid.Row="1" IsChecked="False" />
    </Grid>
</Grid>

MessageManagement 讯息管理

List<MessagePreview> unread = new List<MessagePreview>();

    public bool messagesLocked()
    {
        foreach (MessagePreview m in unread)
        {
            if ((bool)m.checkBox.IsChecked)
                return true;
        }
        return false;
    }

MainWindow C# MainWindow C#

MessageManagement messageManagement;

MessagesPanel1 is a blank StackPanel inside MainWindow MessagesPanel1是MainWindow内的空白StackPanel

if (!messageManagement.messagesLocked())
{
       foreach (Message m in messageManagement.getListOfMessages()
       {
              MessagesPanel1.Children.Add(m)
       }
}

When you add the custom control to the StackPanel it creates a duplicate of the original, which means changing a value on the controls in the StackPanel does not affect the controls in my MessageManagement List. 当您将自定义控件添加到StackPanel时,它会创建原始控件的副本,这意味着更改StackPanel中控件的值不会影响我的MessageManagement List中的控件。

Is there a way that I can reference my original controls so that they change together? 有没有一种方法可以引用我的原始控件,以便它们一起更改? I looked into DataBinding but I'm not sure if that's the right area. 我调查了DataBinding,但不确定是否正确。

Again, You do not make a List of UI elements in WPF. 同样,您不会在WPF中创建UI元素List You use an ItemsControl and set its ItemTemplate Property to whatever UI you need to represent your items: 您使用ItemsControl并将其ItemTemplate属性设置为表示项目所需的任何UI:

 <ItemsControl ItemsSource="{Binding Messages}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <!-- Everything you placed in your usercontrol, or else an instance of your usercontrol itself -->
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

If saying "change" you mead a data, inside WPF you never and ever need to access UI elements directly, as they are subject to change. 如果说“更改”,则意味着要存储数据,在WPF永远也不需要直接访问UI元素,因为它们可能会更改。 What you have to do is to read the data bound to them. 您要做的就是读取绑定到它们的数据。 With correct databinding setupped on that controls you will have always updated information. 通过在控件上设置正确的databinding ,您始终拥有更新的信息。

Accessing UI elements is never easy, but except that, it's completely unreliable way to access your data, as the way control is injected into the VisualTree may be changed, so your code will fail on next update. 访问UI元素从来都不是一件容易的事,但除此之外,它是访问数据的绝对不可靠的方法,因为将控件注入VisualTree 可能会更改,因此您的代码将在下次更新时失败。

For example on how to architect that can have a look here: 例如,有关如何设计架构的信息,可以在这里查看:

WPF Data Binding Examples WPF数据绑定示例

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

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