How to SelectItem of ListView having GridView - c#

I want to select ListViewItem on Edit Button click of button, present in ListView inside GridView. Using MVVM Pattern.
Use case: Edit option in last column in GridViewColumn, on clicking edit button, I want to hide TextBlock and show TextBox, but to do this, I want to first selectItem of ListView on Edit Button's click
In below code,
I'm having ObservableCollection List,
User.cs is as below
private string _username;
private string _password;
private int _age;
private string _city;
public string Username { get => _username; set => _username = value; }
public string Password { get => _password; set => _password = value; }
public int Age { get => _age; set => _age = value; }
public string City { get => _city; set => _city = value; }
private bool _isEdit;
public bool IsEdit
{
get { return _isEdit; }
set
{
_isEdit = value;
OnPropertyChanged(nameof(IsEdit));
}
}
public User()
{
_username = String.Empty;
_password = String.Empty;
_city = String.Empty;
_isEdit = true;
}
public User(string username, string password, int age, string city)
{
this._username = username;
this._password = password;
this._age = age;
this._city = city;
_isEdit = true;
}
View File is as below
<ListView ItemsSource="{Binding List}"
Grid.Row="1"
SelectionMode="Single"
SelectedItem="{Binding SelectedUser}"
x:Uid="Table">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="IsSelected"
Value="{Binding IsEdit, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumnHeader Style="{StaticResource HeaderStyle}">
<ContentControl ContentTemplate="{StaticResource Header}"
Content="Username" />
</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Username}" />
<TextBox Text="{Binding Username}"
Visibility="{Binding IsEdit, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumnHeader Style="{StaticResource HeaderStyle}">Age</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Age}" />
<TextBox Text="{Binding Age}"
Visibility="{Binding IsEdit, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumnHeader Style="{StaticResource HeaderStyle}">City</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding City}" />
<TextBox Text="{Binding City}"
Visibility="{Binding IsEdit, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumnHeader Style="{StaticResource HeaderStyle}">Modify</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Edit"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=DataContext.Edit}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}, Path=ListViewItems}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>

To select an item from code you need to set the Property that is bound to "SelectedItem" and then call a NotifyChange.
In your case it would be inside the Button Click-Event:
SelectedUser=yourItem;
NotifyChange(nameof(SelectedUser))

Related

Binding Button command which inside ListView Item WPF MVVM

I have a ListView that outputs the content. total of 4 columns: Chapter number, title, edit button, delete button
When you click on the button, you need to get the element where it is located (for example, the Chapter number or Chapter name). I tried to do binding via the ListView name and via FindAncestor, but nothing happened.
Please help solve the problem or point out errors
XAML:
<ListView Name="TableOfContents"
ItemsSource="{Binding Path=ContentList}"
Background="{x:Null}" Width="600"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
BorderBrush="{x:Null}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction
Command="{Binding Command}"
CommandParameter="{Binding ElementName=TableOfContents, Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.View>
<GridView>
<GridViewColumn Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ThemeID}" TextWrapping="Wrap"
Foreground="Black" FontSize="30"
TextAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="460">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ThemeName}" TextWrapping="Wrap"
Foreground="Black" FontSize="20"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="40">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="🖊" ToolTip="Редактировать"
Foreground="Black" FontSize="18"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ItemsControl}},
Path=TableOfContentsPageViewModel.EditTheme}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="40">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="❌" ToolTip="Удалить"
Foreground="Black" FontSize="18"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ItemsControl}},
Path=TableOfContentsPageViewModel.DeleteTheme}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
ViewModel:
class TableOfContentsPageViewModel:BaseViewModel, IPageViewModel
{
public string SearchedChapter { get; set; }
public Visibility CanEdit { get; set; } = Visibility.Hidden;
public Theme SelectedTheme { get; set; }
public ObservableCollection<Theme> ContentList { get; set; }
public TableOfContentsPageViewModel()
{
ContentList = new ObservableCollection<Theme>(TrainSQL_Commands.GetAllThemes());
CanEdit = CurrentUser.Role == "Administrator" ? Visibility.Visible : Visibility.Hidden;
}
private ICommand _editTheme;
public ICommand EditTheme
{
get
{
return _editTheme ?? (_editTheme = new RelayCommand(x =>
{
MessageBox.Show("Edit theory");
}));
}
}
private ICommand _deleteTheory;
public ICommand DeleteTheme
{
get
{
return _deleteTheory ?? (_deleteTheory = new RelayCommand(x =>
{
MessageBox.Show("Delete theory");
}));
}
}
}
Image: https://i.stack.imgur.com/cpROA.png
Welcome to SO!
RelativeSource binds to the control itself, not via the DataContext (which make sense when you think about it). You're currently binding to the Path TableOfContentsPageViewModel.DeleteTheme, you need to change that to DataContext.TableOfContentsPageViewModel.DeleteTheme.

DataGrid Cell MultiSelect ComboBox with checkboxes

I have a wpf MVVM application which shows a DataGrid. I have a few columns that are DataGridTextColumns and I want another column to be a MultiSelect Combobox in which shows a checkbox and textblock on each row. The dataSource for the datagrid is different than that of the multiselect combobox I am working towards. My Issue is that I cannot see data (list) in the multiselect combobox when its in the datagrid cell. When I move the code outside of the datagrid I am able to see data. This is my code below
ViewModel:
public class TripInfo : ViewModelBase
{
public TripInfo(bool isVisited, string cityName)
{
IsVisited = isVisited;
CityName = cityName;
}
public Boolean IsVisited { get; set; }
public String CityName { get; set; }
}
public class DataGridViewModel : ViewModelBase
{
ObservableCollection<RecordInfo> infos;
List<TripInfo> tripinfos;
ICommand _command;
public ObservableCollection<RecordInfo> PersonsInfo
{
get
{
return infos;
}
set
{
infos = value;
OnPropertyChanged("PersonsInfo");
}
}
public List<TripInfo> TripsInfo
{
get
{
return tripinfos;
}
set
{
tripinfos = value;
OnPropertyChanged("TripsInfo");
}
}
public DataGridViewModel()
{
PersonsInfo = new ObservableCollection<RecordInfo>();
TripsInfo = new List<TripInfo>();
TripsInfo.Add(new TripInfo(false, "Miami"));
TripsInfo.Add(new TripInfo(true, "Boston"));
TripsInfo.Add(new TripInfo(true, "Los Angeles"));
TripsInfo.Add(new TripInfo(true, "Houston"));
TripsInfo.Add(new TripInfo(false, "Dallas"));
TripsInfo.Add(new TripInfo(false, "Atlantic City"));
TripsInfo.Add(new TripInfo(true, "Chicago"));
GetPersonInfoData();
}
private void GetPersonInfoData()
{
PersonsInfo.Add(new RecordInfo
{
Name = "AA",
Age = 24,
DateOfBirth = new DateTime(1987, 4, 29),
Address = "XXX XXX XXXX"
});
PersonsInfo.Add(new RecordInfo
{
Name = "BB",
Age = 23,
DateOfBirth = new DateTime(1988, 3, 4),
Address = "XXX XXXXX XXX"
});
PersonsInfo.Add(new RecordInfo
{
Name = "CC",
Age = 26,
DateOfBirth = new DateTime(1985, 10, 2),
Address = "XXX XXX X"
});
View.Xaml
<Window.Resources>
<Style x:Key="NameCellStyle" TargetType="DataGridCell">
<Style.Setters>
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
<Setter Property="Background" Value="Aqua"/>
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Name="cmb" Margin="5" Height="20" ItemsSource="{Binding TripsInfo}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Margin="5" IsChecked="{Binding IsVisited}"/>
<TextBlock Margin="5" Text="{Binding CityName}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<DataGrid Grid.Row="1" Name="DGVPersonInfo" ItemsSource="{Binding PersonsInfo}" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Button Content="Remove..." Margin="3"
Command="{Binding Path=DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}">
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="FrameworkElement.HorizontalAlignment" Value="Center" />
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Age" Binding="{Binding Age}" CellStyle="{StaticResource NameCellStyle}"/>
<DataGridTemplateColumn Header="Date Of Birth">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DateOfBirth}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding DateOfBirth}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Address" Binding="{Binding Address}" />
<DataGridTemplateColumn Header="Template">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding TripsInfo}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsVisited}" Width="20" />
<TextBlock Text="{Binding CityName}" Width="100" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
ItemSource or any property of inside a Template is not directly accessible to the DataGrid's DataContext or any other Other Control or Window.
We need to explicitly provide the data Path.
As per your Xaml Code I am not sure where you have bind your View Model, but as per your Remove Button Command, below is how your Drop Down itemSource must be bind.
<ComboBox ItemsSource="{Binding Path=DataContext.TripsInfo, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}">

Binding individual ListView items created in XAML

I have a ListView with ListViewItem's created statically in XAML. I want to bind ListViewItem's properties to different properties in my View Model given as a DataContext for ListView. But my code does not work:
<ListView AlternationCount="2" Name="listView">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Binding.TargetUpdated="TargetUpdated" Text="{Binding Value}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Units}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding About}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<l:PropertyItem Title="title" Value="{Binding Path=DeviceCode}" Units="units" About="about"/>
<l:PropertyItem Title="title" Value="{Binding Path=VendorName}" Units="units" About="about"/>
<l:PropertyItem Title="title" Value="{Binding Path=Version}" Units="units" About="about"/>
</ListView>
Where NumericItem is:
internal class PropertyItem : DependencyObject
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(String), typeof(PropertyItem), new PropertyMetadata(String.Empty));
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(String), typeof(PropertyItem), new PropertyMetadata(String.Empty));
public static readonly DependencyProperty UnitsProperty =
DependencyProperty.Register("Units", typeof(String), typeof(PropertyItem), new PropertyMetadata(String.Empty));
public static readonly DependencyProperty AboutProperty =
DependencyProperty.Register("About", typeof(String), typeof(PropertyItem), new PropertyMetadata(String.Empty));
public String Value
{
get
{
return (String)this.GetValue(ValueProperty);
}
set
{
this.SetValue(ValueProperty, value);
}
}
public String Title
{
get
{
return (String)this.GetValue(TitleProperty);
}
set
{
this.SetValue(TitleProperty, value);
}
}
public String Units
{
get
{
return (String)this.GetValue(UnitsProperty);
}
set
{
this.SetValue(UnitsProperty, value);
}
}
public String About
{
get
{
return (String)this.GetValue(AboutProperty);
}
set
{
this.SetValue(AboutProperty, value);
}
}
}
I found the solution! My PropertyItem class derived from DependencyObject which in turn does not contain property DataContext. That's why the binding does not work. You need to derive from the one who has DataContext property, for example FrameworkElement and it will work!
Try using these Bindings:
<l:PropertyItem Title="title" Value="{Binding Path=DataContext.DeviceCode,
RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" Units="units"
About="about" />
<l:PropertyItem Title="title" Value="{Binding Path=DataContext.VendorName,
RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" Units="units"
About="about"/>
<l:PropertyItem Title="title" Value="{Binding Path=DataContext.Version,
RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" Units="units"
About="about"/>
Here, we're binding to the DataContext of the parent of type ListView... I believe that's what you were after.

List Under ListView Item

I have listview that binding with observable Collection, this listview show the invoice items, any item in invoice maybe has a sub detail (Options), (for example item color),
what i want to ask about is: how to make list view show the item options as list under the main item in listview, i hope my question is clear .. for more clarity look at the image :
What i want is in a yellow color, how to make listview look like the image ?
here's my invoice listview code :
<ListView x:Name="temsReceipt" ItemsSource="{Binding ocItemsReceipt}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Height="40" Width="50"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Item Name" Width="230" DisplayMemberBinding="{Binding ItemName}"/>
<GridViewColumn Header="Item Price" Width="100" DisplayMemberBinding="{Binding ItemPrice}"/>
</GridView>
</ListView.View>
The same think if i used the datagrid
Let's say that you have following classes:
class InvoiceItem
{
public string ItemName { get; set; }
public List<InvoiceOption> Options { get; set; }
}
class InvoiceOption
{
public string OptionName { get; set; }
}
ListView solution:
<ListView x:Name="temsReceipt" ItemsSource="{Binding}">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Height="40" Width="50"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Item Name" Width="230" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding ItemName}" VerticalAlignment="Center"
FontWeight="Bold" FontSize="18"/>
<ListBox ItemsSource="{Binding Options}" Grid.Row="1" Background="Yellow"
HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding OptionName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Item Price" Width="100" DisplayMemberBinding="{Binding ItemPrice}"/>
</GridView>
</ListView.View>
</ListView>
If you want to use DataGrid you can use RowDetailsTemplate:
<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding ItemName}" />
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Margin="2" Background="Yellow">
<TextBlock Text="Options:" />
<ListBox ItemsSource="{Binding Options}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding OptionName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Sample data:
...
public MainWindow()
{
InitializeComponent();
List<InvoiceItem> _source = new List<InvoiceItem>
{
new InvoiceItem
{
ItemName = "Item1",
Options = new List<InvoiceOption>
{
new InvoiceOption { OptionName = "Option1" },
new InvoiceOption { OptionName = "Option2" }
}
},
new InvoiceItem
{
ItemName = "Item2",
Options = new List<InvoiceOption>
{
new InvoiceOption { OptionName = "Option3" },
new InvoiceOption { OptionName = "Option4" }
}
}
};
this.DataContext = _source;
}
...
ListView result:

Usercontrol in datatemplate out of sync

So I want to have multiple tabs with a usercontrol in it, depending on how many items there are in a list. so I think this shoudn t be too hard but .... I start with a new window to make a tabcontroller and bind its itemsource(of the tabcontroler to the list):
<Window x:Class="xxxxx.extraforms.frmownedchamps"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sp="clr-xxxxx.usercontrols.ucoptions"
Title="frmownedchamps" Height="593" Width="350" Loaded="Window_Loaded_1" ResizeMode="NoResize" WindowStyle="None" ShowInTaskbar="False">
<Grid>
<TabControl Name="thetabcontrol">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Label Content="{Binding name}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type sp:ucownedchampviewer}" >
<sp:ucownedchampviewer strname="{Binding Path=name}" strcode="{Binding Path=code}" clclist="{Binding Path=list}" teller="{Binding Path=teller}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>
once the window get loaded it only does thetabcontrol.ItemsSource = settings.clclist;
the clclist is this:
public static List<clc> clclist { get; set; }
public void methodblabla()
{
foreach( xml blabla)
{
clc clctemp = new clc(xmlname, xmlcode);
clclist.Add(clctemp);
}
}
the clc class is:
public class clc
{
private static int counter = 0;
public int teller { get; set; }
public String name { get; set; }
public String code { get; set; }
public ObservableCollection<champion> list { get; set; }
public clc(String name, String code)
{
this.name = name;
this.code = code;
teller = counter;
counter++;
makelist();
}
public void makelist()
{
var bytes = Convert.FromBase64String(code);
var values = new System.Collections.BitArray(bytes);
list = new ObservableCollection<champion>();
int aantal = champions.list.Count;
int teller = 0;
int counter = 0;
for (int x = aantal; x != 0; x--)
{
if (values[x - 1] == true)
{
list.Add(champions.getchampbyid(counter + 1));
teller++;
}
counter++;
}
}
}
my usercontrol:
<UserControl x:Class="xxxxx.usercontrols.ucoptions.ucownedchampviewer"
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:sp="clr-namespace:xxxxx"
mc:Ignorable="d"
d:DesignHeight="564" d:DesignWidth="350" Loaded="UserControl_Loaded">
<Grid Height="624">
<Grid.Resources>
<Style x:Key="Ownedstyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="Red"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding strowned}" Value="Yes">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<StackPanel Margin="0,0,0,12">
<StackPanel Orientation="Horizontal" Margin="5">
<TextBox Name="txtclc" Width="250" Margin="2" Text="{Binding Path=strcode ,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
<Button Name="btnload" Content="Save" Click="btnsave_Click" Width="55" Margin="2"/>
</StackPanel>
<Line Margin="2" />
<StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Stretch" Width="350">
<TextBlock VerticalAlignment="Center">Filter:</TextBlock>
<TextBox Name="txtfilter" Height="30" Grid.Column="0" TextChanged="txtfilter_TextChanged" Margin="5" Width="250" />
<Label Name="lblaantal"></Label>
</StackPanel>
<ListView Name="lsvallchamps" Grid.Column="0" Grid.Row="1" Grid.RowSpan="1" Height="410" Width="auto" ItemContainerStyle="{StaticResource Ownedstyle}" ItemsSource="{Binding Path=clclist ,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" >
<ListView.View>
<GridView>
<GridViewColumn Width="60">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="50" Source="{Binding image}" Stretch="Fill"></Image>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="120" DisplayMemberBinding="{Binding name}">
<GridViewColumnHeader Content="name" Tag="name" Click="SortClick"/>
</GridViewColumn>
<GridViewColumn Width="130" DisplayMemberBinding="{Binding strroles}">
<GridViewColumnHeader Content="strroles" Tag="strroles" Click="SortClick" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Content="testknop" Click="Button_Click" />
<Button Content="Hide" Name="btnhide" Width="150" Height="35" Margin="5" Click="btnhide_Click"></Button>
</StackPanel>
</Grid>
</UserControl>
Sorry for so much code, but mayby better too much then too less code. The problem is that I want the button btnsave to save the txtclc.text to the code and make a new list of it, (and then the listview should be automaticly changed according to it since it is binded to it)
However once I use the code
private void btnsave_Click(object sender, RoutedEventArgs e)
{
settings.clclist[teller].code = txtclc.Text;
settings.clclist[teller].makelist();
}
It does change it! I can see it with debug.writeline that the value has changed in the clclist. BUT the listview in this tab doesn t change! ONLY if I go to an other tab, then back to the first one then it has changed with the right champions. There even is a 2nd problem. O But if I go to an other tab(usercontrol) the txtclc.text is changed as well to the first one! also the list is not updated on the usercontrol, on neither! however the makelist method should change it?
Sorry for this LONG question however I ve been googeling alot and no luck for this problem.
SOLUTION:
Replace Text="{Binding Path=strcode ,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" with Text="{Binding Path=code}" in the usercontrol. and add INotifyPropertyChanged to the clc class, Thx to Rachel!
You have two problems here.
The first, is that your classes don't implement INotifyPropertyChanged, so the UI has no idea that it's objects have changed. Make your clc class implement this interface, and raise the PropertyChanged event when the code and name properties change so the UI knows to update.
The second problem is that by default, WPF will re-use a template if possible. For example, your TabControl is creating one instance of your UserControl, and when you switch tabs it is simply changing the DataContext behind the UserControl. If txtclc.Text is not bound to something in the DataContext, then it will not change because you are viewing the exact same TextBox regardless of which tab you are viewing. The solution is to add a property to your DataContext object to store the Text of the txtclc TextBox, and bind the property.

Categories

Resources