WPF在运行时基于配置文件对StackPanel中的XAML元素进行排序

问题描述

我正在使用带有Caliburn.Micro的MVVM模式开发WPF应用程序 我有一个配置文件,其中包含XAML元素应在StackPanel内部的位置

# in this case RU_ELEMENT should be at the top,EN_ELEMENT second and DE_ELEMENT last
EN_ELEMENT = 1
DE_ELEMENT = 2
RU_ELEMENT = 0

这似乎很基本,但我找不到解决方法。我发现了这个线程:change the children index of stackpanel in wpf,但是对于我所追求的来说,以这种方式更改它似乎太复杂了。我只需要从变量中设置元素的索引。我觉得应该有一种更简单的方法。我还可以使用其他一些可能比StackPanel更合适的布局面板。

XAML:


<!--     Language1 -->
<TextBlock Text="English" Foreground="DarkGray" FontSize="16"/>
<TextBox
    VerticalAlignment="Top"
    Height="150"
    Text="{Binding SelectedItem.ValueEN,UpdateSourceTrigger=PropertyChanged}"
    cm:Message.Attach="[Event GotFocus] = [Action FocusedTextBox('english')]" />

<!--     Language2 -->
<TextBlock Text="German" Foreground="DarkGray" FontSize="16"/>
<TextBox
    VerticalAlignment="Top"
    Height="150"
    Text="{Binding SelectedItem.ValueDE,UpdateSourceTrigger=PropertyChanged}"
    cm:Message.Attach="[Event GotFocus] = [Action FocusedTextBox('german')]" />

在旁注:与以前的所有语言(Java,Python,JS)相比,我发现WPF和C#通常没有太多的讨论和“如何做”指南,因此在线研究事物通常是徒劳的为我而死。我不确定为什么会这样,因为C#是一种非常流行的语言,但是我真的很难在网上寻求帮助。

解决方法

一个解决方案可能是使用将托管xaml元素的class WidgetDragTree(QtWidgets.QTreeWidget): # ... def mousePressEvent(self,event): # fix for [unknown] bug on windows where clicking on a combo child of an # item widget also sends back some mouseMoveEvents item = self.itemAt(event.pos()) if item and self.itemWidget(item,0): # if the item has a widget,make a list of child combo boxes combos = self.itemWidget(item,0).findChildren(QtWidgets.QComboBox) underMouseWidget = QtWidgets.QApplication.widgetAt(event.globalPos()) if underMouseWidget in combos: return super().mousePressEvent(event) 。您可以绑定ItemsControl之类的项目 然后,您可以轻松地在相应的ViewModel中对项目进行排序。像这样:

<ItemsControl ItemsSource="{Binding ListOfItems} ...

请注意,public BindableCollection<YourElement> ListOfItems {get;set;} ... ListOfItems.Sort() 类应具有比较器。

编辑:根据要求,我将对其进行更详细的说明:

在Xaml中,您必须像这样声明一个ItemsControl:

YourElement

在后端,您应该首先创建一个类,该类将在ItemsControl中表示您的项目。例如:

    <ItemsControl ItemsSource="{Binding ListOfItems}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Language}" Foreground="DarkGray" FontSize="16"/>
                    <TextBox
                        VerticalAlignment="Top"
                        Height="150"
                        Text="{Binding TextValue,UpdateSourceTrigger=PropertyChanged}"
                        cm:Message.Attach="[Event GotFocus] = [Action FocusedTextBox($this)]" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

最后,在ViewModel中,您需要创建与ItemsControl绑定的项目列表,如下所示:

public Class MyItem{
    public string Language {get;set;}
    public string TextValue {get;set;}
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...