0

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

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

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

ParameterBool:标签+复选框

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

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

...

我在第一次尝试使用 DataTemplateSelector 时就做到了这一点。

很好,工作“很好”..

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

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

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

每个 Parameter 类都有一个 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. 放入datatemplate资源

  3. 不要忘记将它放入 datatemplateselector 类

直接在我的课堂上拥有我的“控件”,我只有这一种代码和平..?!

4

2 回答 2

1

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

至于 textchanged 或 click-events,你应该将你的“ontextchanged”或“isCheckedChanged”挂在绑定目标的设置器中(例如 parameter.Text 或 parameter.IsTrue)。按钮的 OnClick 应该替换为适当的命令。

无论你做什么:不要在代码后面实例化控件......这是最糟糕的方法。

于 2014-06-26T12:26:03.517 回答
0

好的,经过几个小时的玩耍、研究、阅读和测试..

这是我的实际解决方案,可以在多个窗口中正常工作!

请留下一些评论,改进,无论如何..谢谢。

我现在有一个 Parameter.cs 和 Parameter.xaml

参数.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>

Parameter.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;
    }
}

现在我只需将 Parameter.xaml 添加到我想使用这些参数的每个窗口到其资源中:

SomeWindow.xaml

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

@SnowballTwo 你的意思是这种方式吗?

于 2014-06-27T09:43:07.697 回答