【问题标题】:Reference a WPF Control added to a StackPanel引用添加到 StackPanel 的 WPF 控件
【发布时间】:2013-01-16 16:12:47
【问题描述】:

这是我几天来一直试图解决的问题,但我还没有找到好的解决方案。

我有一个包含 StackPanel 的主 WPF 窗口。我还有一个名为“MessageManagement”的类,其中包含一个名为“MessagePreview”的自定义 WPF 控件列表。

消息预览

<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>

消息管理

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#

MessageManagement messageManagement;

MessagesPanel1 是 MainWindow 中的空白 StackPanel

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

当您将自定义控件添加到 StackPanel 时,它会创建原始控件的副本,这意味着更改 StackPanel 中控件的值不会影响我的 MessageManagement List 中的控件。

有没有一种方法可以引用我的原始控件,以便它们一起更改?我查看了 DataBinding,但不确定这是否是正确的区域。

【问题讨论】:

  • 什么?!发布您的 xaml 和代码。此外,如果您需要一个控件来显示多个项目,这些项目将是 ItemsControl 或其派生词之一(例如 ListBox
  • 您是在消息控件中使用两种方式还是一种方式绑定?我不认为您的控件列表包含控件的副本,因为 UserControl 是一个引用类型...
  • 这听起来像是 DataBinding 的工作。与其让管理器包含自定义控件列表,不如让它只保存数据 - 例如消息文本。然后使用某种转发器控件(例如 ListBox)并创建一个 ItemTemplate 以便它为每个项目使用您的消息控件,并将该转发器绑定到您的消息集合。这不是一项简单的任务,但有了某种教程(或像 WPF 4 Unleashed 这样的好书),这并不难。
  • 我对我的帖子进行了更改以包含代码,希望这能让问题更清晰。

标签: c# wpf controls stackpanel


【解决方案1】:

同样,您不会在 WPF 中创建 List 的 UI 元素。您使用 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>

【讨论】:

    【解决方案2】:

    如果说“更改”,您会看到一个数据,在 WPF 内部,您永远不会需要直接访问 UI 元素,因为它们可能会发生变化。您要做的是读取绑定到它们的数据。在该控件上设置正确的databinding,您始终更新信息。

    访问UI 元素绝非易事,但除此之外,访问数据的方式完全不可靠,因为注入VisualTree 的控制方式可能会改变,所以你的代码下次更新会失败。

    例如关于如何架构的可以看看这里:

    WPF Data Binding Examples

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多