How can I initialize TabItem content on TabItem load? - c#

Is there a way to initialize Tab content on Tab load? I'm having an issue, when Tab is created it doesnt initialize it components immediately. Only when I click on Tab the content will show up.
<TabControl
ItemsSource="{Binding Items}">
<TabControl.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Text="{Binding TabName}"><TextBlock.Background><SolidColorBrush /></TextBlock.Background></TextBlock>
<Button Name="btnDelete" DockPanel.Dock="Right" Margin="5,0,0,0" Padding="0" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}" BorderBrush="#00000000">
<Image Source="/WPF_AccApp;component/Images/11.gif" Height="11" Width="11"></Image>
</Button>
<DockPanel.Background>
<SolidColorBrush />
</DockPanel.Background>
</DockPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<views:TabItemView />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
Button click event
private void AddInvoice_Click(object sender, RoutedEventArgs e)
{
count++;
string s = string.Format("Tab {0}", count);
mainViewModel.Items.Add(new ItemViewModel(s));
this.DataContext = mainViewModel;
if (count == 1)
{
//this is as work around
// mainViewModel.Items.Add(new ItemViewModel(s));
// mainViewModel.Items.RemoveAt(1);
}
}

Found solution https://social.msdn.microsoft.com/Forums/vstudio/en-US/8043441a-95bb-4f70-b64c-a76f89980068/tabcontrol-getting-the-work-done-in-viewmodel-when-selectionchanged?forum=wpf
You need to add Selected Tab Index property and bind it to TabControl

Related

Binding parameter to a nested ListView using SelectedItem

I'm pretty new to coding in c# and I'm trying on a wpf app to transfer data between different folders.
To visualize the folders and subfolders I've got a tabcontrol with different mainfolders, and under each tab a ListView with information on the subfolders.
All data is gathered in a BindingList 'Klinieken', which is filled with objects 'Kliniek' (mainfolders) which contains objects 'Patient' (subfolders) which is filled with information about said folder. Here is the .xaml file for the mainwindow:
<Grid x:Name="LayoutRoot" Background="#555555">
<Grid.RowDefinitions>
<RowDefinition Height="420" />
<RowDefinition Height="116" />
</Grid.RowDefinitions>
<Grid x:Name="KliniekTabs" Background="#555555" Grid.Row="0" Margin="10 10 10 10">
<TabControl ItemsSource="{Binding Klinieken}"
SelectedItem="{Binding BronKliniek}"
TabStripPlacement="Top">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding KliniekNaam}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding Path=Patienten}"
SelectedItem="{Binding Path=SelectedPatient}">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Patientnaam"
Width="250"
DisplayMemberBinding="{Binding PatientNaam}"/>
<GridViewColumn Header="Zisnr"
Width="250"
DisplayMemberBinding="{Binding PatientZis}"/>
<GridViewColumn Header="Aanmaakdatum"
Width="250"
DisplayMemberBinding="{Binding AanmaakDatum}"/>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
<Grid x:Name="WindowControls" Background="#777777" Grid.Row="1" Margin="100 5 100 10">
<StackPanel Orientation="Vertical">
<Label Margin="-80 0 0 0" HorizontalAlignment="Center">Doel kliniek</Label>
<ComboBox ItemsSource="{Binding Path=Klinieken}"
x:Name="doelKliniekDD"
SelectedItem="{Binding DoelKliniek}"
Margin="-120 0 0 0"
HorizontalAlignment="Center">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=KliniekNaam}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<StackPanel Orientation="Horizontal" Margin="20 0 0 0" Height="50" VerticalAlignment="Bottom" HorizontalAlignment="Center">
<Button Height="25" Style="{StaticResource Button_Orange}" Command="{Binding TransferButtonCommand}" CommandParameter="{Binding ElementName=window, Mode=OneWay}" Margin="0 0 10 0">Transfer</Button>
<Button Height="25" Style="{StaticResource Button_Orange}" Command="{Binding CopyButtonCommand}" CommandParameter="{Binding ElementName=window, Mode=OneWay}" Margin="10 0 20 0">Kopieer</Button>
<Button Height="25" Style="{StaticResource Button_Grey}" Command="{Binding CloseCommand}" CommandParameter="{Binding ElementName=window, Mode=OneWay}" Margin="20 0 0 0">Cancel</Button>
</StackPanel>
</StackPanel>
</Grid>
</Grid>
And here is the MainViewModel that is referenced in the .xaml:
//attributen
string monacoDirectory;
List<string> aanwezigeClinics;
Installation installation;
//constructor
public MainViewModel()
{
monacoDirectory = ConfigurationManager.AppSettings["monacoDirectory"];
aanwezigeClinics = new List<string>(Directory.GetDirectories(monacoDirectory, "*", SearchOption.TopDirectoryOnly));
aanwezigeClinics.Remove(monacoDirectory + #"\defaults");
aanwezigeClinics.Remove(monacoDirectory + #"\physics");
installation = new Installation(aanwezigeClinics);
Klinieken = new BindingList<Kliniek>();
foreach (var kliniek in installation.Klinieken)
{
Klinieken.Add(kliniek);
}
}
private Kliniek _doelKliniek;
private Kliniek _bronKliniek;
private Patient _selectedPatient;
private BindingList<Kliniek> _klinieken = new BindingList<Kliniek>();
public BindingList<Kliniek> Klinieken
{
get { return _klinieken; }
set { _klinieken = value; }
}
public Kliniek DoelKliniek
{
get { return _doelKliniek; }
set
{
_doelKliniek = value;
OnPropertyChanged();
}
}
public Kliniek BronKliniek
{
get { return _bronKliniek; }
set
{
_bronKliniek = value;
OnPropertyChanged();
}
}
public Patient SelectedPatient
{
get { return _selectedPatient; }
set
{
_selectedPatient = value;
MessageBox.Show("hoi");
OnPropertyChanged();
}
}
The data shows up in the gui just fine, which i was quite happy with. And using SelectedItem on the TabControl and the ComboBox i use later worked out beautifully aswell, but I just cant seem to get the SelectedItem on the ListView to work. I have added a button to test the output of the fields and SelectedPatient always returns as null.
If i check the 'Live Visual Tree' in VS and go to the properties of the ListView i can see the Patient as SelectedItem, so that tells me its not a selection but a binding problem. Furthermore ive tried to google for nested bindings, but the suggestions there didnt change anything about my situation.
Is a nested binding like this possible, or should i take a whole different approach?
Had a similar problem quite a while ago. The suggestions below solved it for me at the time.
Use SelectedValue instead of SelectedItem. This is because SelectedItem doesn't change until the control has been validated. SelectedValue changes whenever the user selects an item. The code you could use is as follows:
SelectedValue="{Binding BronKliniek, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
For the button part, try to provide CommandParameter="{Binding}" instead of CommandParameter="{Binding ElementName=window, Mode=OneWay}". This way, you'll get the value of the current DataContext of the button, which you can then use to extract the data you want from this DataContext.

How to change the background color of TreeViewItem when clicking in the WPF treeview?

I want to change the background of StackPanel when clicking TextBlock.
enter image description here
now background is bule! I want to change it!
<TreeView Name="tvView" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=ChildNodes}">
<Grid VerticalAlignment="Top" Margin="0">
<StackPanel Orientation="Horizontal" d:LayoutOverrides="Height">
<TextBlock Name="ConfidenceLevelReminderText" Text="!" FontWeight="Bold" HorizontalAlignment="Center" Foreground="#FF0000" Width="{Binding Path=ConfidenceLevelWidth}" Margin="0,0,0,0"></TextBlock>
<TextBlock TextWrapping="Wrap"
Padding="0,3,0,3"
Text="{Binding Path=Name}"
ToolTip="{Binding Path=NameToolTip}"
Tag="{Binding Path=TagInfo}"
MouseLeftButtonDown="name_MouseLeftButtonDown"
FontSize="14"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="#FF666666"
Margin="0"
Width="{Binding Path=TextWidth}"
Cursor="Hand"/>
<Button x:Name="btnIngnore" Width="{Binding Path=IgnoreWidth}" Click="btn_ignore_Click" Tag="{Binding Path=NodeId}" Margin="0" BorderThickness="0" Background="{x:Null}" Style="{StaticResource ButtonStyle32}" IsEnabled="{Binding Path=IgnoreWidth,Converter={StaticResource itb}}" Cursor="Hand">
<TextBlock Text="xxxx" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" FontSize="12" Foreground="#FF666666"/>
</Button>
</StackPanel>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
If you want
to change the background of StackPanel when clicking TextBlock.
You can add EventSetter to the TextBlock's Style and handle event in the event handler.
<TextBlock Text="...">
<TextBlock.Style>
<Style TargetType="TextBlock">
<EventSetter Event="MouseDown" Handler="Mouse_LBtnDown"/>
</Style>
</TextBlock.Style>
</TextBlock>
private void Mouse_LBtnDown(object sender, MouseButtonEventArgs e)
{
StackPanel stp = null;
var visParent = VisualTreeHelper.GetParent(sender as FrameworkElement);
while (stp == null && visParent != null)
{
stp = visParent as StackPanel;
visParent = VisualTreeHelper.GetParent(visParent);
}
if (stp == null) { return; }
stp.Background = Brushes.Coral;
}
For make it reusable and adjustable you could make a behavior from the event handler.
If you don't want what you have asked, then rethink your question and ask new one.

Tabcontrol with different pages (included in xaml or extern page) as tabcontent

Hello and thanks for reading and maybe helping :-)
My Code below with statements.
I have my MainWindow.xaml in which I have my CheckBox and TabControl.
<CheckBox Grid.Column="8" Grid.Row="2" Name="checkBoxCommon" HorizontalAlignment="Right" VerticalAlignment="Center" IsChecked="{Binding IsCheckedCommon}"/>
<Grid Grid.Column="0" Grid.ColumnSpan="10" Grid.Row="4">
<TabControl ItemsSource="{Binding Path=DpConfigCol>
<TabControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Path=DpConfigName}>
<ContentControl.Resources>
<DataTemplate DataType="types:ConfigCommon">
</DataTemplate>
<DataTemplate DataType="types:ConfigAdress">
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl>
<ContentControl.Resources>
<DataTemplate DataType="types:ConfigCommon">
<TextBlock Text="hallo" Width="150"/>
</DataTemplate>
<DataTemplate DataType="types:ConfigAdress">
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
If I tick my checkbox it will add a new model to my ObservableCollection().
private bool _isCheckedCommon;
public bool IsCheckedCommon
{
get { return _isCheckedCommon; }
set
{
_isCheckedCommon = value;
if (_isCheckedCommon == true)
{
DpConfigCol.Add(new ConfigCommon("Common"));
}
else
{
foreach (object item in DpConfigCol)
{
if (item.GetType().ToString()==typeof(ConfigCommon).FullName.ToString())
{
DpConfigCol.Remove(item);
break;
}
}
}
return;
}
}
I made a binding to my tabcontrol with this Collection called DpConfigCol.
And now my question:
How do I make the properties (from my model: ConfigCommon) visible in my tabcontrol.ContentTemplate? If there are more than one checkbox with even more Models?
Is there a way to implement in that Tabcontrol.contentTemplate more than one Template for more than one model?
TLDR; (read only the title)
I also had to develop an app that used tabs once. You can use <Frame> inside your tabs and set its Content to what ever XAML page you want

why are the converters being called again?

In my windows phone app one of the pages contains LongListSelector. In that LongListSelector I am using some converters. When the LongListSelector Loaded the Converters are being called as usual. But when I call ScrollTo() method to scroll to a specific item of the LongListSelector, the converters are being called again. Why are the converters being called again? What does ScrollTo() method do that causes converters to be called again?
Sample Code:
XAML:
<phone:LongListSelector ItemTemplate="{StaticResource LLSItemSource}"
Name="ChatListBox">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Background="Transparent"
Visibility="{Binding ID, Converter={StaticResource visibilityConverter}}"
Margin="0,6">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="delete"
Click="ContextMenuItem_Click" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Border Background="Black"
HorizontalAlignment="Center"
Padding="30,5,30,8"
CornerRadius="20">
<TextBlock Text="{Binding Date, Converter={StaticResource dateStringConverter}}"
Foreground="White"
FontSize="20" />
</Border>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
CS:
private void ContextMenuItem_Click(object sender, RoutedEventArgs e)
{
string header = (sender as MenuItem).Header.ToString();
MessageModel selectedListBoxItem = (sender as MenuItem).DataContext as MessageModel;
if (selectedListBoxItem == null)
return;
if (header == "delete")
{
DeleteItemByID(selectedListBoxItem.ID);
if (ChatListBox.ItemsSource.Count > 0)
{
ChatListBox.ScrollTo(ChatListBox.ItemsSource[delIndex - 1]); // here I am scrolling to the last item that causes converters to be called again
}
}
}
You are written converter for longlistselector items. On loading every item in selector its get executing to convert value on given template

wpf check list box

I m new to wpf.In order to get check list box functionality ,I have added below xaml to my code,but there is no output in my screen.only blank,what it could be?
<TabItem Header="Samples" >
<ListBox Margin="10" Width="373" Height="236">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="MyText"/>
<CheckBox IsChecked="False"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</TabItem>
just have a look at this basic sample
http://merill.net/2009/10/wpf-checked-listbox/
List box is a bit wired for such task..Have a look at ItemsControl.
Here is the code i use:
<ItemsControl
ItemsSource="{Binding ***}" IsTabStop="False">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox
Content="{Binding Name}"
IsChecked="{Binding IsSelected}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Replace your code with this
<TabItem Header="Roles" >
<ListBox Margin="10" Width="373" Height="236">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="MyText"/>
<CheckBox IsChecked="False"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBoxItem>Hi</ListBoxItem>
</ListBox>
</TabItem>
and tell us if it still shows blank
Better still, just use the new CheckListBox control in the Extended WPF Toolkit
http://wpftoolkit.codeplex.com/wikipage?title=CheckListBox&referringTitle=Home
This might help
1.Inorder to work datatemplate you must specify itemsource, here i have bounded a Stateslist a collection of items into it.
2.Also set the Datacontext to ViewModel or the CodeBehind as datacontext.
3.Datacontext will distribute the StateList properties collection to the listbox itemsource
using codebehind -
public Window1()
{
InitializeComponent();
this.DataContext = this;
LoadData();
}
using viewmodel
public Window1()
{
InitializeComponent();
DataContext = new Window1ViewModel();
LoadData();
}
//MyItemsource Property for listbox
private ObservableCollection<States> _stateslist;
public ObservableCollection<States> StatesList
{
get { return _stateslist; }
set
{
_stateslist = value;
RaisePropertyChanged(() => StatesList);
}
}
// Sample Data Loading
public void LoadData()
{
StatesList = new ObservableCollection<States>();
StatesList.Add(new States
{
StateName = "Kerala"
});
StatesList.Add(new States
{
StateName = "Karnataka"
});
StatesList.Add(new States
{
StateName = "Goa"
});
}
Window1.Xaml
<ListBox ItemsSource="{Binding StatesList}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox IsChecked="{Binding IsSelected"} Content="{Binding StateName}" />
<TextBox Text="{Binding TextBoxValue}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Check this out it isworking..you are using TabItem but you didnt define it in TabControl
<TabControl>
<TabItem Header="Tab1">
<ListBox Margin="10" Width="373" Height="236">
<ListBox.Items>
<StackPanel Orientation="Horizontal">
<TextBlock Text="MyText"/>
<CheckBox IsChecked="False"/>
</StackPanel>
</ListBox.Items>
</ListBox>
</TabItem>
</TabControl>
If you are new in WPF use XamlPadX it will give you great help to practice out on it..

Categories