I am building a tool and want to have a listview with parameters.
i have a base class called Parameter and many different derived classes, for example: ParameterAddress, ParameterBool, ParameterString, ParameterScreen, ...
Each Parameter looks a bit different..
ParameterBool: Label + Checkbox
ParameterString: Label + Textbox
ParamterAddress: Label + Textbox + Button (for a new Dialog)
...
I have done this in my first try with an DataTemplateSelector.
Was nice, works "well"..
In my window i implemented the events like text changed, button clicked and so on..
but now i want to use this parameter view in another window too and dont want to copy the same text changed, button clicked events in each window again..
So my second try was to build in this into my parameter class.
Each Parameter class will have an Stackpanel and each derived class adds its Controls into it and can so handle whatever events just in one place!
But now in my listview only comes up the text "....Stackpanel" .
I think way 1 was a better direction, way 2 could work anyway ..
But what would be the "best" way?
EDIT
here are my actual datatemplates:
<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>
in my opinion its very unusable..
you have to maintain so many peaces of code to work..
create a new template
put it into the datatemplate resource
dont forget to put it into the datatemplateselector class
with having my "controls" directly in my class i have only this one peace of code.. ?!
Okay, after some hours playing around, researching, reading and testing ..
Here is my actual solution, which works fine in multiple windows !
Please leave some comments, improvements, whatever .. Thanks.
I am having now a Parameter.cs and Parameter.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>
Snippet of 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;
}
}
now i simply add to each window where i want to use these parameters the Parameter.xaml to its Resources:
SomeWindow.xaml
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Parameter.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
@SnowballTwo did you mean this way of doing it?