This is my first post on StackOverflow and also my first Question.
I had created a UserControl in WPF with the MVVM Pattern (called Block).
This UserControl should be used in another UserControl, as DataTemplate of a ListBox (called Sector).
The Block Control should be used as standalone and as DataTemplate for different UserControls.
If I set the DataContext in the View of Block, the standalone Version works great, but not as part of the Sector View.
If I don´t set the DataContext in the View of Block, it works in Sector but don’t standalone.
My question is, is it the only way to leave the DataContext in the View of Block and set it in the View I used the Control or the ViewModel?
Here is my Code:
Model of Block:
public class BlockModel : ModelBase
{
#region private Variables
string blockName = "Block";
string blockContent = "00000";
#endregion private Variables
#region Properties
public string BlockName
{
get { return blockName; }
set { blockName = value; NotifyPropertyChange("BlockName "); }
}
public string BlockContent
{
get { return blockContent; }
set { blockContent = value; NotifyPropertyChange("BlockContent"); }
}
#endregion Properties
#region ctor
public BlockModel () { }
#endregion ctor
}
ViewModel of Block:
public class BlockViewModel : ViewModelBase
{
#region private Variables
string charToFill = "0";
DelegateCommand fillWithChar;
BlockModel dataModel = new BlockModel();
#endregion private Variables
#region Properties
public Models. BlockModel DataModel
{
get { return dataModel; }
set { dataModel = value; }
}
public string BlockContent
{
get { return dataModel. BlockContent; }
set
{
if (dataModel. BlockContent != value)
{
dataModel. BlockContent = value;
NotifyPropertyChange ("BlockContent");
}
}
}
public string BlockName
{
get { return dataModel. BlockName; }
set
{
if (dataModel. BlockName != value)
{
dataModel. BlockName = value;
NotifyPropertyChange("BlockName");
}
}
}
public string CharToFill
{
get { return charToFill; }
set
{
if (charToFill != value)
{
charToFill = value;
NotifyPropertyChange ("CharToFill");
}
}
}
public ICommand FillWithChar
{
get
{
if (fillWithChar == null)
fillWithChar = new DelegateCommand(FillText);
return fillWithChar;
}
}
#endregion Properties
#region ctor
public BlockViewModel()
{
}
#endregion ctor
#region Methods
private void FillText()
{
CodingBlockContent = CodingBlockContent.PadLeft(32, charToFill[0]);
}
#endregion Methods
}
View of Block:
<UserControl x:Class="…./Block"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:…/Controls"
mc:Ignorable="d" d:DesignWidth="460" d:DesignHeight="44">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="124" />
<ColumnDefinition Width="301" />
<ColumnDefinition Width="30"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding BlockName}"
HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="14" Margin="2,6"/>
<ComboBox FontFamily="Consolas" Grid.Row="00" Grid.Column="1"
Text="{Binding BlockContent, Mode=TwoWay}"
Tag="{Binding BlockName}" Name="cbxBlock" FontSize="14"
HorizontalAlignment="Left" VerticalAlignment="Center" Width="290" Margin="1,4,0,5" IsEditable="True" Height="26">
<ComboBoxItem Content=""></ComboBoxItem>
<ComboBoxItem Content="0000000000000"></ComboBoxItem>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Horizontal">
<TextBox Margin="10,2,0,2" Text="0" Width="24" FontSize="14" Name="tbxChar" MaxLength="1"></TextBox>
<TextBlock Margin="10,2,0,2" Text="auffüllen" VerticalAlignment="Center" FontSize="14"></TextBlock>
<Button Margin="10,2,0,2" Content="Ausführen" Width="100" Command="{Binding FillWithChar}"></Button>
</StackPanel>
</ComboBox>
<TextBlock Grid.Row="0" Width="30" Grid.Column="2" Text="{Binding CodingBlockContent.Length}"
HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="14" Margin="2,6,0,6" Grid.ColumnSpan="2"/>
</Grid>
Model of Sector:
public class SectorModel
{
#region private Variables
int blockAmount = 4;
string sectorNumber = "Sektor";
int blockBegin = 0;
bool isSectorInUse = false;
#endregion private Variables
#region Properties
public string SectorNumber
{
get { return sectorNumber; }
set { sectorNumber = value;}
}
public int BlockBegin
{
get { return blockBegin; }
set
{
blockBegin = value;
}
}
public bool IsSectorInUse
{
get { return isSectorInUse; }
set { isSectorInUse = value;}
}
public int BlockAmount
{
get { return blockAmount; }
set
{
blockAmount = value;;
}
}
#endregion Properties
public SectorModel()
{
}
}
ViewModel of Sector:
public class SectorViewModel : ViewModelBase
{
#region private Variables
SectorModel dataModel = new SectorModel();
ObservableCollection<BlockViewModel> sectorBlocks = new ObservableCollection<BlockViewModel>();
#endregion private Variables
#region Properties
public SectorModel DataModel
{
get { return dataModel; }
set { dataModel = value; }
}
public ObservableCollection<BlockViewModel> SectorBlocks
{
get { return sectorBlocks; }
set { sectorBlocks = value; NotifyPropertyChange ("SectorBlocks"); }
}
public string SectorNumber
{
get { return "Sektor " + DataModel.SectorNumber; }
set { DataModel.SectorNumber = value; NotifyPropertyChange ("SectorNumber"); }
}
public int BlockBegin
{
get { return DataModel.BlockBegin; }
set
{
DataModel.BlockBegin = value;
SetBlocks();
OnPropertyChanged("BlockBegin");
}
}
public bool IsSectorInUse
{
get { return DataModel.IsSectorInUse; }
set { DataModel.IsSectorInUse = value; NotifyPropertyChange ("IsSectorInUse"); }
}
public int BlockAmount
{
get { return DataModel.BlockAmount; }
set
{
DataModel.BlockAmount = value;
SetBlocks();
NotifyPropertyChange ("CodingBlockAmount");
}
}
#endregion Properties
void SetBlocks()
{
while (SectorBlocks.Count != BlockAmount)
{
SectorBlocks.Add(new BlockViewModel());
}
int begin = BlockBegin;
foreach (BlockViewModel block in SectorBlocks)
{
block.CodingBlockName = "Block " + begin.ToString().PadLeft(2, '0');
block++;
}
}
public SectorViewModel()
{
SetBlocks();
}
}
View of Sector:
<UserControl xmlns:Views="clr-namespace:…/RFIDControls" x:Class="…/Sector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="473">
<Border BorderBrush="Black" BorderThickness="0,0,0,1">
<Expander Name="expMain" Margin="0,0,4,0">
<Expander.Header>
<Grid Name="grdHeader">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="300" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Height="24" Text="{Binding SectorNumber}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="14" FontWeight="Bold" Panel.ZIndex="98"/>
<CheckBox Grid.Column="2" VerticalAlignment="Center" IsChecked="{Binding IsSectorInUse}"></CheckBox>
</Grid>
</Expander.Header>
<Grid>
<ListBox ItemsSource="{Binding SectorBlocks}" Name="listBox">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type Views:BlockViewModel}">
<Views:Block/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Expander>
</Border>
Thank you.
With kind regards from Germany
Dominik
PS: I hope my English is not so bad as I suppose