gpt4 book ai didi

c# - 在 MVVM 中动态填充 Wrappannel

转载 作者:太空宇宙 更新时间:2023-11-03 22:14:56 24 4
gpt4 key购买 nike

这是关于使用 MVVM 的最佳实践建议。

我需要在将元素放入其中时填充包装面板。元素不统一,可以是标签,也可以是文本框。根据参数的值,添加的元素会有所不同。

我在后面的代码中做到了这一点。现在我正在将整个事情转移到 MVVM 模型的过程中,我坚持在不影响 MVVM 核心原则的情况下执行此操作。在这段代码中,我将 UI 元素和逻辑内容放在一起,它们紧密相关;而且我已经无法将两者分开以安装 MVVM。

我尝试在 VM 中创建 UI 元素,填充 UIElement 类型的 ObservableCollection 并将其绑定(bind)到 itemssource 属性(随后我将 wrappanel 更改为 listview 以便在整个过程中有效)。但这并没有奏效,因为当我绑定(bind)元素时,代码无法理解哪个 UIelement。

下面是我需要分开的代码部分:

private void CreateVisulaQueryContent() {

VisualQueryObject visualQueryData = new VisualQueryObject();

VisualQueryObject helperVisualQueryObject = DraggedData as VisualQueryObject;


//***Taking a copy of the static DraggedData object to be bound

visualQueryData.ColumnDiscriptor = helperVisualQueryObject.ColumnDiscriptor;

visualQueryData.ComparedValue = helperVisualQueryObject.ComparedValue;

visualQueryData.JoinWithColumnDescriptor = helperVisualQueryObject.JoinWithColumnDescriptor;

visualQueryData.LabelType = helperVisualQueryObject.LabelType;
visualQueryData.OperatorValue = helperVisualQueryObject.OperatorValue;


if (visualQueryData.LabelType == "column")
{

ColumnDescriptionObject descriptionValue = visualQueryData.ColumnDiscriptor;
Label droppedElement = new Label();

Binding binding = new Binding();
binding.Source = visualQueryData;
binding.Path = new PropertyPath("ColumnDiscriptor");
binding.Mode = BindingMode.TwoWay;
droppedElement.SetBinding(Label.DataContextProperty, binding);

droppedElement.Content = visualQueryData.ColumnDiscriptor.TableName + "." + visualQueryData.ColumnDiscriptor.ColumnName;


droppedElement.Foreground = Brushes.White;
droppedElement.Background = Brushes.DarkOrange;

droppedElement.BorderThickness = new Thickness(5);

droppedLabel.MouseDoubleClick += columnLabel_MouseDown;
ViewUIElements.Add(droppedElement);

}
else if (visualQueryData.LabelType == "controller")
{

Label droppedElement = new Label();

Binding binding = new Binding();
binding.Source = visualQueryData;
binding.Path = new PropertyPath("OperatorValue");
binding.Mode = BindingMode.TwoWay;
droppedElement.SetBinding(Label.DataContextProperty, binding);


droppedElement.Content = draggedContent.OperatorValue;
droppedElement.Foreground = Brushes.White;
droppedElement.Background = Brushes.Crimson;
droppedElement.BorderThickness = new Thickness(5);

droppedElement.MouseDoubleClick += columnLabel_MouseDown;

ViewUIElements.Add(new Label());

}
else if (visualQueryData.LabelType == "value")
{
TextBox droppedElement = new TextBox();

Binding binding = new Binding();
binding.Source = visualQueryData;
binding.Path = new PropertyPath("ComparedValue");
binding.Mode = BindingMode.TwoWay;
droppedElement.SetBinding(TextBox.TextProperty, binding);

droppedElement.MouseDoubleClick += columnLabel_MouseDown;

ViewUIElements.Add(droppedElement);
}

QueryDesignerModel.QueryDesignHelperCollection.Add(visualQueryData);

}

非常感谢任何帮助!

最佳答案

正如我所 promise 的,我创建了一个示例,其中 ViewModels 中没有 UIElements

首先,我从你的方法中删除了很多代码:

public class MainViewModel
{
public MainViewModel()
{
//For demonstration
this.ViewUIElements = new ObservableCollection<VisualQueryObject>
{
new VisualQueryObject{LabelType = "column", ColumnDiscriptor = new DescriptionModel("Table1", "Column2") },
new VisualQueryObject{LabelType = "controller"},
new VisualQueryObject{LabelType = "value"},
};
}

public void UpdateCollection(VisualQueryObject helperVisualQueryObject)
{
VisualQueryObject visualQueryData = new VisualQueryObject();
//I would remove copying, but maybe it is intended behavior
//***Taking a copy of the static DraggedData object to be bound
visualQueryData.ColumnDiscriptor = helperVisualQueryObject.ColumnDiscriptor;
visualQueryData.ComparedValue = helperVisualQueryObject.ComparedValue;
visualQueryData.JoinWithColumnDescriptor = helperVisualQueryObject.JoinWithColumnDescriptor;
visualQueryData.LabelType = helperVisualQueryObject.LabelType;
visualQueryData.OperatorValue = helperVisualQueryObject.OperatorValue;

this.ViewUIElements.Add(visualQueryData);

//QueryDesignerModel.QueryDesignHelperCollection.Add(visualQueryData); //I don't know what this method does
}

public ObservableCollection<VisualQueryObject> ViewUIElements { get; private set; }
}

然后我创建了 DataTemplateSelector 类,我在其中放置了问题中函数的 if 子句:

public class QueryObjectDateTemplateSelector : DataTemplateSelector
{
public DataTemplate ColumnTemplate { get; set; }

public DataTemplate ControllerTemplate { get; set; }

public DataTemplate ValueTemplate { get; set; }

public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
{
var visualQueryData = item as VisualQueryObject;
if (visualQueryData == null)
return null;

if (visualQueryData.LabelType == "column")
return ColumnTemplate;
else if (visualQueryData.LabelType == "controller")
return ControllerTemplate;
else if (visualQueryData.LabelType == "value")
return ValueTemplate;
else return null;

}
}

这几乎就是全部。其他一切都在 xaml 中:

<Window.Resources>
<ItemsPanelTemplate x:Key="WrapPanelTemplate">
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>

<DataTemplate x:Key="ColumnDataTemplate">
<Label DataContext="{Binding ColumnDiscriptor}" Foreground="White" Background="DarkOrange" BorderThickness="5">
<TextBlock>
<Run Text="{Binding TableName}"/><Run Text="."/><Run Text="{Binding ColumnName}"/>
</TextBlock>
</Label>
</DataTemplate>
<DataTemplate x:Key="ControllerDataTemplate">
<Label Content="Controller"/>
</DataTemplate>
<DataTemplate x:Key="ValueDataTemplate">
<TextBox Text="Value"/>
</DataTemplate>
<local:QueryObjectDateTemplateSelector x:Key="ModelSelector"
ColumnTemplate="{StaticResource ColumnDataTemplate}"
ControllerTemplate="{StaticResource ControllerDataTemplate}"
ValueTemplate="{StaticResource ValueDataTemplate}"/>
</Window.Resources>
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>

<Grid>
<ItemsControl ItemsSource="{Binding ViewUIElements}" ItemsPanel="{StaticResource WrapPanelTemplate}"
ItemTemplateSelector="{StaticResource ModelSelector}"/>
</Grid>

我只编写了列模板,其他模板也应该用 xaml 重写。所以现在你可以调用这个方法:

((MainViewModel)this.DataContext).UpdateCollection(DraggedData as VisualQueryObject);

关于c# - 在 MVVM 中动态填充 Wrappannel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5429988/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com