实现“参数视图”的最佳方式比如Visual Studio中的TemplateSelector之类的

本文关键字:Studio Visual 中的 TemplateSelector 最佳 参数 视图 参数视图 实现 方式比 | 更新日期: 2023-09-27 18:10:33

我正在构建一个工具,并希望有一个列表视图与参数。

我有一个名为Parameter的基类和许多不同的派生类,例如:ParameterAddress, ParameterBool, ParameterString, ParameterScreen,…

每个参数看起来有点不同…

ParameterBool: Label + Checkbox

参数字符串:标签+文本框

参数地址:标签+文本框+按钮(用于新建对话框)

我在第一次尝试使用DataTemplateSelector时已经这样做了。

Was nice, works "well".

在我的窗口中,我实现了像文本更改,按钮点击等事件。

但是现在我想在另一个窗口中使用这个参数视图,也不想在每个窗口中复制相同的文本更改,按钮单击事件。

所以我的第二次尝试是把它构建到我的参数类中

每个参数类将有一个Stackpanel,每个派生类将其控件添加到其中,因此可以在一个地方处理任何事件!

但是现在在我的列表视图中只出现文本"...."Stackpanel"。

我认为方法1是一个更好的方向,方法2也可以。

但是什么是"最好"的方法呢?

编辑

下面是我的实际数据模板:

    <Window.Resources>
    <DataTemplate x:Key="textBoxTemplate">
        <TextBox Text="{Binding Path=Value}" Width="100"></TextBox>
    </DataTemplate>
    <DataTemplate x:Key="checkBoxTemplate">
        <CheckBox IsChecked="{Binding Path=Value}" IsThreeState="False"></CheckBox>
    </DataTemplate>
    <DataTemplate x:Key="screen_template">
        <StackPanel Orientation="Horizontal">
            <TextBox Text="{Binding Path=Value}" Width="100"></TextBox>
            <Button Content="..." Click="btn_screenlist_Click" />
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="address_template">
        <StackPanel Orientation="Horizontal">
            <TextBox Text="{Binding Path=Value}" Width="100"></TextBox>
            <Button Content="..." Click="btn_address_Click" />
        </StackPanel>
    </DataTemplate>
    <local:ParameterTemplateSelector
        x:Key="parameterTemplateSelector"
        TextBoxTemplate="{StaticResource textBoxTemplate}"
        CheckBoxTemplate="{StaticResource checkBoxTemplate}"
        Screen_template="{StaticResource screen_template}"
        Address_template="{StaticResource address_template}"
        />
</Window.Resources>

在我看来,它是非常不可用的。

你必须维护这么多的代码来工作。

  1. 创建新模板

  2. 将其放入数据模板资源

  3. 别忘了把它放到datatemplateselector类中

有我的"控件"直接在我的类,我只有这一个和平的代码。?!

实现“参数视图”的最佳方式比如Visual Studio中的TemplateSelector之类的

您应该使datatemplate没有指向派生参数类类型的键。Wpf将自动为每个类显示最合适的模板。

对于textchanged或click-events,你应该将你的"ontextchanged"或"isCheckedChanged "挂起到绑定目标的setter中(例如参数)。文本或参数。itrue)。按钮的OnClick应该用一个合适的命令代替。

不管你做了什么:不要在代码后面实例化控件…这是最糟糕的做法。

好了,经过几个小时的玩,研究,阅读和测试…

这是我的实际解决方案,它在多个窗口中工作得很好!

请留下一些评论,改进,无论什么…谢谢。

我现在有一个参数。cs和参数。xaml

Parameter.xaml

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:locale="clr-namespace:tests"
>
<DataTemplate DataType="{x:Type locale:ParameterString}">
    <TextBox Text="{Binding Value}" MinWidth="100"></TextBox>
</DataTemplate>
<DataTemplate DataType="{x:Type locale:ParameterBool}">
    <CheckBox IsChecked="{Binding Value}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type locale:ParameterAddress}">
    <StackPanel Orientation="Horizontal">
        <Label Content="{Binding Name}"/>
        <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" MinWidth="100"/>
        <Button
            Content="..."
            Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
            Command="{Binding EditAddrCmd}"
            />
    </StackPanel>
</DataTemplate>

cs
public class ParameterAddress : Parameter
{
    ControllerList controllers;
    #region constructors
    public ParameterAddress (ControllerList controllers, String address)
    {
        this.controllers=controllers;
        Name="Address";
        Value=address;
        EditAddrCmd=new RelayCommand(ex => EditAddrCmdExec(), cex => EditAddrCmdCanExec());
    }
    // ..
    #endregion // constructors
    #region commands
    public ICommand EditAddrCmd { get; internal set; }
    private void EditAddrCmdExec ()
    {
        // open dialog to edit address and save to <Value>
    }
    private bool EditAddrCmdCanExec ()
    {
        return true;
    }
    #endregion // comannds
    public override bool isValid ()
    {
        return true;
    }
}

现在我只是添加到每个窗口,我想使用这些参数的参数。xaml到其资源:

SomeWindow.xaml

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Parameter.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

@SnowballTwo你是指这样做吗?