【问题标题】:C# WPF dynamically creating and binding comboboxes via XAMLC# WPF 通过 XAML 动态创建和绑定组合框
【发布时间】:2020-03-15 19:57:58
【问题描述】:

我对 WPF 和 MVVM 还很陌生,现在我遇到了一个问题,到目前为止我还没有找到解决方案。我正在更新一个使用 Windows.Forms 的旧程序。由于我目前正在阅读和学习 WPF,我认为在 WPF 中重做程序是一个好主意。

我的程序以特殊格式读取一个 ASCII 文件,并从中创建一个 Fragment 对象列表。然后列表显示在动态创建的 GUI 中。 Fragment 对象如下所示:

public class Fragment
{
    public string Name { get; set; }

    public List<Value> Values { get; set; }

    public int ActiveIndex { get; set; }
}

public class Value
{
    public string Name { get; set; }

    public int BitValue { get; set; }
}

所以:每个Fragment 可以在属性中有多个Value 对象。活动值也从 ASCII 文件中读取,其索引(来自List&lt;Value&gt; 中的值的索引)保存在ActiveIndex 属性中。

我已经准备了一个简单的 XAML-Layout 来显示结果。

<ScrollViewer VerticalScrollBarVisibility="Auto">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <StackPanel Margin="0, 3"></StackPanel>
        <GridSplitter Grid.Column="1" ResizeDirection="Columns" Background="DarkGray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" IsEnabled="True" Width="1"></GridSplitter>
        <StackPanel Grid.Column="2" Margin="0, 3"></StackPanel>
    </Grid>
</ScrollViewer>

所以:在第一个 StackPanel 中,我想将所有 Fragment.Name 显示为标签,在第二个 StackPanel 中,我想为每个 Fragment 创建一个 ComboBox,其中包含所有 Fragment.Values 显示 Value.Name 属性。 ActiveIndex 绑定到组合框的 SelectedIndex。

我可以在文件隐藏的代码中完美地做到这一点,但这会让我和其他看到这一点的人非常头疼。我明白,可以在 XAML 中做到这一点,但我真的不明白它是如何完成的。 谁能向我暗示正确的方向,谁能实现这种行为?此外,如果有更好的 GUI 方法来处理它,我完全愿意接受建议。当前的只是从工具的 Windows.Forms 版本的简单转移。

【问题讨论】:

    标签: c# wpf xaml dynamic


    【解决方案1】:

    您可以使用 ItemsControl:

    <ScrollViewer VerticalScrollBarVisibility="Auto">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <ItemsControl ItemsSource="{Binding NameOfYourListOfFragments}">
                <ItemsControl.ItemsPanel>
                    <StackPanel Margin="0, 3"></StackPanel>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <Label Content="{Binding Name}"/>
                </itemsControl.ItemsTemplate>
            </ItemsControl>
    
            <GridSplitter Grid.Column="1" ResizeDirection="Columns" Background="DarkGray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" IsEnabled="True" Width="1"></GridSplitter>
            <ItemsControl Grid.Column="2" ItemsSource="{Binding NameOfYourListOfFragments}">
                <ItemsControl.ItemsPanel>
                    <StackPanel  Margin="0, 3"></StackPanel>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemsTemplate>
                    <Combobox ItemsSource="{Binding Values}" DisplayMemberPath="Name" SelectedIndex="{Binding ActiveIndex}"/>
                </ItemsControl.ItemsTemplate>
            </ItemsControl>
        </Grid>
    </ScrollViewer>
    

    使用ItemsPanel,您可以告诉ItemsControl,您的GUI 元素应该安排在哪种面板中。 ItemTemplate 告诉您,您的 ItemsControl 中的元素是什么样的。

    如果您使用ObservableCollection,您还可以在运行时添加或删除条目,GUI 将自动更新。

    为了使绑定充分发挥作用,您的类可能还必须强制 INotifyPropertyChanged 并且您必须在属性的设置器中调用 PropertyChanged 事件。

    【讨论】:

    • 非常感谢!这让我走上了正确的道路!通过阅读有关 ItemControl 和一些更改的内容,它现在就像一个魅力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-27
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多