I have a list of objects in my mainViewmodel. When selecting in the listbox, depending on the selected type, a groupbox for this type should be visible and the properties should be binded.
I am not sure how i can achive this. I tried some stuff but i dont get it worked.
Foreach type of the ISimulator i have a groupbox and when I select it in the listbox, i try to show the right groupbox and bind the properties to that.
Thanks in advance
Xaml:
<Window x:Class="ControlCenter.Simulators.Gui.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
DataContext="MainViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="1000">
<Grid x:Name="MainGrid" Margin="10,0,0,0" >
<Button Content="Add Simulator" HorizontalAlignment="Left" Margin="44,34,0,0" VerticalAlignment="Top" Width="88" />
<GroupBox x:Name="gb_Vehicle" Header="{Binding SimulatorId}" Margin="177,0,10,0" Visibility="Hidden">
<Grid Height="402" Margin="10,0,12,0">
<Label Content="StartCoordinates(x,y)" HorizontalAlignment="Left" Margin="21,21,0,0" VerticalAlignment="Top"/>
<Label x:Name="tb_Radius_Header" Content="Radius" HorizontalAlignment="Left" VerticalAlignment="Top" Width="126" Margin="21,91,0,0"/>
<Label x:Name="tb_Freq_Header" Content="Frequency" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="21,159,0,0"/>
<Label x:Name="tb_DeltaT_Header" Content="Delta T" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="21,213,0,0"/>
<Label x:Name="tb_Velocity_Header" Content="Velocity" HorizontalAlignment="Left" Margin="21,278,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="tb_Cord_X" HorizontalAlignment="Left" Margin="30,52,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="51" Text="{Binding SelectedItem.XCord, ElementName=lb_Vehicles,Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<TextBox x:Name="tb_Cord_Y" HorizontalAlignment="Left" Margin="96,52,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="51" Text="{Binding SelectedItem.YCord, ElementName=lb_Vehicles,Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<TextBox x:Name="tb_Radius" HorizontalAlignment="Left" Margin="30,122,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="52" Text="{Binding SelectedItem.Radius, ElementName=lb_Vehicles,Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}" />
<TextBox x:Name="tb_DealtaT" HorizontalAlignment="Left" Margin="30,244,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding SelectedItem.DeltaT, ElementName=lb_Vehicles,Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<TextBox x:Name="tb_Freq" HorizontalAlignment="Left" Margin="30,183,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding SelectedItem.Frequency, ElementName=lb_Vehicles,Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<TextBox x:Name="tb_Velocity" HorizontalAlignment="Left" Margin="30,309,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding SelectedItem.Velocity, ElementName=lb_Vehicles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"/>
<WpfPlot Name="Plot" Margin="292,2,10,-2"/>
<Button x:Name="bt_Start" Content="Start" HorizontalAlignment="Left" Margin="21,366,0,0" VerticalAlignment="Top" Width="91" Height="26" />
<Button x:Name="bt_pos" Content="Draw" HorizontalAlignment="Left" Margin="134,366,0,0" VerticalAlignment="Top" Height="26" Width="77" />
</Grid>
</GroupBox>
<GroupBox x:Name="gb_Traffic" Header="{Binding SimulatorId}" Margin="177,0,10,0" Visibility="Hidden">
<Grid>
<ComboBox HorizontalAlignment="Left" Margin="27,57,0,0" VerticalAlignment="Top" Width="120"/>
<Label Content="Traffic Light Type" HorizontalAlignment="Left" Margin="27,10,0,0" VerticalAlignment="Top" Width="120"/>
<Label Content="Position (x,y)" HorizontalAlignment="Left" Margin="27,107,0,0" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="tb_Traffic_X" HorizontalAlignment="Left" Margin="27,162,0,0" TextWrapping="Wrap" Text="x" VerticalAlignment="Top" Width="60"/>
<TextBox x:Name="tb_Traffic_Y" HorizontalAlignment="Left" Margin="27,196,0,0" TextWrapping="Wrap" Text="y" VerticalAlignment="Top" Width="60"/>
<Label Content="PhasePlan" HorizontalAlignment="Left" Margin="220,55,0,0" VerticalAlignment="Top" Width="92"/>
<ListView d:ItemsSource="{d:SampleData ItemCount=5}" Margin="220,86,10,127">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="OrderId" />
<GridViewColumn Header="Color"/>
<GridViewColumn Header="TotalDuration"/>
<GridViewColumn Header="BlinkDuration"/>
<GridViewColumn Header="Action"/>
</GridView>
</ListView.View>
</ListView>
<Button x:Name="bt_LoadConfig" Content="Load Config" HorizontalAlignment="Left" Margin="524,13,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.044,-0.116" Width="107"/>
<GroupBox Header="New Phase" Margin="10,313,189,20">
<Grid>
<Label Content="Color" HorizontalAlignment="Left" Margin="10,6,0,35" Height="30" Width="73"/>
<Label Content="Total Duration" HorizontalAlignment="Left" Margin="176,10,0,31" Height="30" Width="110"/>
<Label Content="Blink Duration" HorizontalAlignment="Left" Margin="341,7,0,34" Height="30" Width="110"/>
<ComboBox x:Name="cb_TrafficColor" HorizontalAlignment="Left" Margin="10,36,0,0" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="tb_TotalDuration" HorizontalAlignment="Left" Margin="176,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="tb_BlinkDuration" HorizontalAlignment="Left" Margin="341,39,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<Button x:Name="bt_AddPhase" Content="Add" HorizontalAlignment="Left" Margin="489,37,0,0" VerticalAlignment="Top" Width="62"/>
</Grid>
</GroupBox>
<Button x:Name="bt_SaveConfig" Content="Save Config" HorizontalAlignment="Left" Margin="651,13,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.044,-0.116" Width="107"/>
<Button x:Name="bt_StartTraffic" Content="Start" HorizontalAlignment="Left" Margin="669,397,0,0" VerticalAlignment="Top" Width="89"/>
</Grid>
</GroupBox>
<GroupBox x:Name="gb_AddSimulator" Header="Add Simulator" Margin="190,0,0,0" Visibility="Visible">
<Grid Margin="10,0,21,0">
<Label x:Name="tb_ObjectId_Header" Content="ObjectId" HorizontalAlignment="Left" Margin="241,29,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="tb_ObjectId" HorizontalAlignment="Left" Margin="222,66,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=SimulatorModel.Config.ObjectID, Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<Label x:Name="tb_IPAdress_Header" Content="IPAdress" HorizontalAlignment="Left" Margin="54,84,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="tb_IPAdress" HorizontalAlignment="Left" Margin="54,115,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=SimulatorModel.Config.IpAddress, Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<Label x:Name="tb_PortTCP_Header" Content="Port TCP" HorizontalAlignment="Left" Margin="236,84,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="tb_PortUDP" HorizontalAlignment="Left" Margin="55,169,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=SimulatorModel.Config.PortUDP, Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<TextBox x:Name="tb_PortTCP" HorizontalAlignment="Left" Margin="222,115,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=SimulatorModel.Config.PortTCP, Mode=TwoWay ,ValidatesOnDataErrors=True , UpdateSourceTrigger=PropertyChanged}"/>
<Label x:Name="tb_PortGrpc_Header_" Content="Port GRPC" HorizontalAlignment="Left" Margin="236,138,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="tb_PortGrpc" HorizontalAlignment="Left" Margin="222,169,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=SimulatorModel.Config.PortGRPC, Mode=TwoWay ,ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
<Label x:Name="tb_PortUDP_Header1" Content="Port UDP" HorizontalAlignment="Left" Margin="57,138,0,0" VerticalAlignment="Top"/>
<Button x:Name="bt_Add" Content="Add" HorizontalAlignment="Left" Margin="144,240,0,0" VerticalAlignment="Top" Width="119" Command="{Binding AddSimulatorCommand}" />
<ComboBox x:Name="cb_SimulatorType" HorizontalAlignment="Left" Margin="54,64,0,0" VerticalAlignment="Top" Width="120"/>
<Label x:Name="tb_PortGrpc_Header__Copy" Content="Simulator Type" HorizontalAlignment="Left" Margin="57,29,0,0" VerticalAlignment="Top"/>
</Grid>
</GroupBox>
<ListBox x:Name="lb_Simulators" d:ItemsSource="{Binding }" Margin="0,94,818,10"/>
</Grid>
</Window>
MainWindow.cs:
public partial class MainWindow : Window
{
private ILogger _logger;
public MainWindow()
{
InitializeComponent();
var mainViewModel = new MainViewModel(_logger);
this.DataContext = mainViewModel;
mainViewModel.SimulatorModels = new List<SimulatorModel>()
{
new SimulatorModel("1", null, null),
new SimulatorModel("2", null, null),
new SimulatorModel("3", null, null),
};
//lb_Simulators.ItemsSource = mainViewModel.SimulatorModels;
//lb_Simulators.DisplayMemberPath = "ID";
//gb_AddSimulator.DataContext = mainViewModel.SimulatorModel.Config;
//_logger.Information("Gui startet");
}
private void SetGroupBox(GroupBoxNames name, ISimulator simulator)
{
gb_Vehicle.Visibility = Visibility.Hidden;
gb_Traffic.Visibility = Visibility.Hidden;
gb_AddSimulator.Visibility = Visibility.Hidden;
switch (name)
{
case GroupBoxNames.AddSimulator:
gb_AddSimulator.Visibility = Visibility.Visible;
break;
case GroupBoxNames.Traffic:
gb_Traffic.Visibility = Visibility.Visible;
gb_Traffic.DataContext = simulator;
break;
case GroupBoxNames.Vehicle:
gb_Vehicle.Visibility = Visibility.Visible;
gb_Vehicle.DataContext = simulator;
break;
default:
break;
}
}
MainViewModel:
private ILogger _logger;
public IList<SimulatorModel> SimulatorModels { get; set; }
public SimulatorModel SimulatorModel { get; set; }
public ISimulator Simulator { get; set; }
public ICommand AddSimulatorCommand;
public ICommand RemoveSimulatorCommand;
public ICommand LoadSimulatorConfigCommand;
public ICommand SaveSimulatorConfigCommand;
public ICommand AddPhaseCommand;
public ICommand AddStartSimulatorCommand;
public bool CanStart { get; private set; } = true;
public event PropertyChangedEventHandler? PropertyChanged;
SimulatorModel:
public class SimulatorModel
{
public string ID { get; set; }
public SimulatorConfigModel Config { get; set; }
public ISimulator Simulator { get; set; }
public SimulatorModel(string id,SimulatorConfigModel configModel, ISimulator simulator)
{
ID = id;
Config = configModel;
Simulator = simulator;
}
}
Whenever you need dynamic data type based views you usually have to define a DataTemplate for each. Using the DataTemplate makes manual control of the GroupBox.Visibility obsolete and significantly reduces lines of code related to the related logic. See Microsoft Docs: Data Templating Overview
The following example shows how to display a dedicated GroupBox based on three imaginary ISimulator implementations: SimulatorA, SimulatorB and SimulatorC.
The associated GroupBox itself is hosted in a DataTemplate - one for each ISimulator implementation.
A ContentControl is used to render the DataTemplate. ContentControl.Comtent is bound to the SimulatorModel.Simulator property i.e. the ISimulator instance of the currently selected item of the ListBox:
<Window>
<Window.Resources>
<DataTemplate DataType="{x:Type SimulatorA}">
<GroupBox x:Name="gb_Vehicle">
...
</GroupBox>
</DataTemplate>
<DataTemplate DataType="{x:Type SimulatorB}">
<GroupBox x:Name="gb_Traffic">
...
</GroupBox>
</DataTemplate>
<DataTemplate DataType="{x:Type SimulatorC}">
<GroupBox x:Name="gb_AddSimulator">
...
</GroupBox>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListBox x:Name="SimulatorList"
ItemsSource="{Binding SimulatorModels}" />
<!-- Host for the GroupBox that is rendered via DataTemplate
based on the SimulatorModel.Simulator property.
Instead of binding directly to the ListBox.SelectedItem like below,
you can bind to a MainViewModel.SelectedSimulatorModel property, which is bound to the ListBox.SelectedItem -->
<ContenControl Content="{Binding ElementName=SimulatorList, Path=SelectedItem.Simulator}" />
</StackPanel>
</Window>
You should bind the ListBox, or XAML elements in general, rather than assigning values explicitly in code-behind. Especially in an MVVM scenario where you always focus on the data models rather than on the view's elements: you only update the data model and let the framework take care of the GUI via data binding. If you have to update the source collection dynamically, make the source collection e.g., SimulatorModels of type ObservableCollectio<T>.
Related
I have just started to learn the MVVM methodolgy. I have written a simple application that basically is a application form. My UserControl window is a bunch of labels and textboxes. I bind the textboxes to elements in an Application class. The user can either choose to load the data from a Google spreadsheet or hard code the data. This all works great. I also want to be able to print the form with the values in the textboxes. The window layout prints just fine but the value in the textboxes. I am just doing a printobjext.printvisual command. My question is how do I print the contents of the textboxes, do I need to bind the data in some other way?
Here is part of my UserControl XAML window. just eliminating redundent code.
<UserControl x:Class="ApplicationForm.Views.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ApplicationForm"
xmlns:model="clr-namespace:ApplicationForm.Model"
xmlns:views="clr-namespace:ApplicationForm.Views"
xmlns:viewModel="clr-namespace:ApplicationForm.ViewModel"
mc:Ignorable="d"
Height="980" Width="800" Background="#FFDAFDF2">
<!--<UserControl.Resources>
<ResourceDictionary>
<viewModel:ApplicationViewModel x:Key="AppViewModel"/>
</ResourceDictionary>
</UserControl.Resources>-->
<Grid x:Name="grdAppForm">
<Grid x:Name="grdAppFormGrid" DocumentViewerBase.IsMasterPage="True" VirtualizingPanel.VirtualizationMode="Standard"
VirtualizingPanel.IsVirtualizingWhenGrouping="True" HorizontalAlignment="Center" VerticalAlignment="Center" Height="820" Width="700">
<Label x:Name="lblName" Content="Name:" Height="28" Width="58" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,10,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16" />
<TextBox x:Name="tbxName" DataContext="{Binding Applicants, Mode=TwoWay}" Text="{Binding FullName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, BindsDirectlyToSource=True}"
Height="22" Width="215" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="83,10,0,0" FontFamily="Arial" FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" FontSize="16" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblFamilySize" Content="Family Size:" Height="28" Width="102" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="362,10,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16" />
<Label x:Name="lblFamO" Content="O:" Height="28" Width="27" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="461,10,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="txbFamO" DataContext="{Binding Applicants, Mode=TwoWay}" Text="{Binding Path=FamilyO, Mode=TwoWay, BindsDirectlyToSource=True}" Height="22" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="486,10,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblFamA" Content="A:" Height="28" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="506,10,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="tbxFamA" DataContext="{Binding Applicants}" Text="{Binding Path=FamilyA, Mode=TwoWay}" Height="22" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="531,10,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblFamC" Content="C:" Height="28" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="552,10,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="txtFamC" DataContext="{Binding Applicants}" Text="{Binding Path=FamilyC, Mode=TwoWay}" Height="22" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="577,10,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblEqual" Content="=" Height="28" Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="601,10,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="16"/>
<TextBox x:Name="tbxFamTot" DataContext="{Binding Applicants}" Text="{Binding Path=FamilyTotal,
Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Height="22" Width="30"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="624,10,0,0" FontFamily="Arial"
FontWeight="Bold" FontSize="16" BorderBrush="Black" BorderThickness="0,0,0,3" IsTabStop="False" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblRenewalDate" Content="Renewal Date:" Height="28" Width="119" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="127,60,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="tbxRenewalDate" DataContext="{Binding Applicants}" Text="{Binding Path=RenewalDate, Mode=TwoWay}" Height="22" Width="180" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="247,60,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<Label x:Name="lblAddressDisp" Content="Address:" Height="28" Width="80" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="80,115,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold"/>
<TextBox x:Name="tbxAddress1" DataContext="{Binding Applicants, Mode=TwoWay}" Text="{Binding Path=Address1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, BindsDirectlyToSource=True}" Height="22" Width="344" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="162,115,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" TextWrapping="Wrap" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
<TextBox x:Name="tbxAddress2" DataContext="{Binding Applicants}" Text="{Binding Path=Address2, Mode=TwoWay}" Height="22" Width="426" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="80,145,0,0" FontFamily="Arial" FontSize="16" FontWeight="Bold" TextWrapping="Wrap" BorderThickness="0,0,0,3" BorderBrush="Black" VerticalContentAlignment="Bottom"/>
</grid>
<Grid x:Name="grdButtonsGrid" HorizontalAlignment="Center" Height="80" Width="700" Margin="20, 880,0,0">
<Button x:Name="btnLoadApplicant" Command="{Binding LoadApplicantCommand}"
HorizontalAlignment="Left" Height="43" Margin="60,25,0,0" VerticalAlignment="Top"
Width="78" FontFamily="Arial" FontSize="14.667" Background="#FFDAFDF2" BorderThickness="2">
<TextBlock Text="Load Applicant" TextWrapping="Wrap" />
</Button>
<Button x:Name="btnGetApplicant" Command="{Binding GetApplicantCommand}"
HorizontalAlignment="Left" Height="43" Margin="150,25,0,0" VerticalAlignment="Top"
Width="95" FontFamily="Arial" FontSize="14.667" Background="#FFDAFDF2" BorderThickness="2">
<TextBlock Text="Get Applicant By Name" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="WrapWithOverflow" />
</Button>
<Button x:Name="btnPrintApplicant" Command="{Binding PrintApplicantCommand}"
HorizontalAlignment="Left" Height="43" Margin="255,25,0,0" VerticalAlignment="Top"
Width="70" FontFamily="Arial" FontSize="14.667" Background="#FFDAFDF2" BorderThickness="2">
<TextBlock Text="Print Applicant" TextWrapping="Wrap"/>
</Button>
<Button x:Name="btnClearData" Command="{Binding ClearDataCommand}"
HorizontalAlignment="Left" Height="43" Margin="335,25,0,0" VerticalAlignment="Top"
Width="58" FontFamily="Arial" FontSize="14.667" Background="#FFDAFDF2" BorderThickness="2">
<TextBlock Text="Clear Data" TextWrapping="Wrap"/>
</Button>
<Button x:Name="btnClose" Content="Close" Command="{Binding CloseCommand}"
HorizontalAlignment="Left" Height="43" Margin="440,25,0,0" VerticalAlignment="Top"
Width="58" FontFamily="Arial" FontSize="14.667" Background="#FFDAFDF2" BorderThickness="2">
</Button>
</Grid>
</grid>
Here is part of my Application class in my ApplicationModel.
namespace ApplicationForm.Model
{
public class ApplicationModel
{
}
public class Applicant : INotifyPropertyChanged
{
private string firstName;
private string lastName;
private string familyO;
private string familyA;
private string familyC;
private string renewalDate;
private string address1;
private string address2;
private string city;
private string state;
private string zip;
private string phoneNumber;
private string name1Birthday;
private string name2;
private string name2Birthday;
private string name3;
private string name3Birthday;
private string name4;
private string name4Birthday;
private string name5;
private string name5Birthday;
private string name6;
private string name6Birthday;
private string name7;
private string name7Birthday;
private string name8;
private string name8Birthday;
public string FirstName
{
get
{
return firstName;
}
set
{
if (firstName != value)
{
firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
}
public string LastName
{
get { return lastName; }
set
{
if (lastName != value)
{
lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
}
}
}
public string FullName
{
get
{
return firstName + " " + lastName;
}
}
public string FamilyO
{
get { return familyO; }
set
{
if (familyO != value)
{
familyO = value;
RaisePropertyChanged("FamilyO");
}
}
}
public string FamilyA
{
get { return familyA; }
set
{
if (familyA != value)
{
familyA = value;
RaisePropertyChanged("FamilyA");
}
}
}
}
}
And here is my print routine in ApplicationViewModel.
public void PrintApplicant(object selectedItem)
{
ApplicationView view = new ApplicationView();
PrintDialog prnt = new PrintDialog();
ObservableCollection<Applicant> applicants = new ObservableCollection<Applicant>();
applicants = Applicants;
if (prnt.ShowDialog() == true)
{
Size pageSize = new Size(prnt.PrintableAreaWidth - 30, prnt.PrintableAreaHeight - 30);
view.grdAppFormGrid.Measure(pageSize);
view.grdAppFormGrid.Arrange(new Rect(5, 5, pageSize.Width, pageSize.Height));
prnt.PrintVisual(view.grdAppFormGrid, applicants[0].FullName);
}
}
I'm trying to update the controls present on my Main Window based on the listviewitem selected by the user, but when the listviewitem selection is changed the controls do not update.
I used this post as reference How to dynamically change a WPF control's template using a checkbox?
EDIT: I initially used ContentTemplate but changed this to DataTemplate based on suggestions, however it still is not updating
The XMAL for my Main Window is
<Window.Resources>
<DataTemplate x:Key="Default">
<Grid Margin="20,280,0,0" />
</DataTemplate>
<DataTemplate x:Key="ERAFileSelect">
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="218" Margin="20,280,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid Name="grdFileSelect">
<Label x:Name="lblProcessContent" Content="Drag File or Manually Select File" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<TextBox x:Name="txtEraFileName" HorizontalAlignment="Left" Height="23" Margin="10,80,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="235"/>
<Button x:Name="btnSelectFiles" Content="Manually Select File(s)" HorizontalAlignment="Left" Margin="10,161,0,0" VerticalAlignment="Top" Width="235" Height="45"/>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="FCSFileSelect">
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="218" Margin="20,280,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid Name="grdFileSelect">
<Label x:Name="lblProcessContent" Content="Drag File or Manually Select Files" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<TextBox x:Name="txtFCSFileName_TQ02" HorizontalAlignment="Left" Height="23" Margin="10,40,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ02" Content="Select" HorizontalAlignment="Left" Margin="189,37,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
<TextBox x:Name="txtFCSFileName_TQ11" HorizontalAlignment="Left" Height="23" Margin="10,105,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ11" Content="Selec" HorizontalAlignment="Left" Margin="189,100,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
<TextBox x:Name="txtFCSFileName_TQ16" HorizontalAlignment="Left" Height="23" Margin="10,170,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="174"/>
<Button x:Name="btnSelectFiles_TQ16" Content="Select" HorizontalAlignment="Left" Margin="189,165,0,0" VerticalAlignment="Top" Width="56" Height="28"/>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid Margin="0,0,2,0">
<GroupBox x:Name="gbxProgress" Header="Progress" HorizontalAlignment="Left" Margin="298,105,0,0" VerticalAlignment="Top" Height="445" Width="462" Foreground="Black">
<ListBox x:Name="lbxProgress" HorizontalAlignment="Left" Height="408" Margin="10,10,0,0" VerticalAlignment="Top" Width="431" Foreground="Black" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Progress.Message}" />
</GroupBox>
<Button x:Name="btnStart" Content="Start" HorizontalAlignment="Left" Margin="20,513,0,0" VerticalAlignment="Top" Width="100" Height="37" IsEnabled="{Binding Properties.StartButtonEnabled}" Click="btnStart_Click"/>
<Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Left" Margin="177,513,0,0" VerticalAlignment="Top" Width="100" Height="37"/>
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="70" Margin="20,21,0,0" VerticalAlignment="Top" Width="740" CornerRadius="15">
<Grid>
<Image HorizontalAlignment ="Left" Margin="10" Height="50" Width="50" VerticalAlignment="Center" Source="/Lib/Icons/User.png" />
<TextBlock Name="txtUser" FontSize="20" Height="30" Width="200" Foreground="Red" HorizontalAlignment="Left" Margin="78,19,0,19"/>
<Image HorizontalAlignment ="Left" Margin="443,8,0,10" Height="50" Width="50" VerticalAlignment="Center" Source="Lib/Icons/Watch.png" />
<TextBlock x:Name="txtRunTime" FontSize="20" Height="30" Width="200" Foreground="Red" HorizontalAlignment="Left" Margin="519,19,0,19" Text="{Binding AppRunTime.TimeElapsed}" />
</Grid>
</Border>
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="144" Margin="20,119,0,0" VerticalAlignment="Top" Width="257" CornerRadius="15">
<Grid>
<Label x:Name="lblProcessSelection" Content="Process Selection" HorizontalAlignment="Center" VerticalAlignment="Top" Width="257" HorizontalContentAlignment="Center"/>
<ListView x:Name="lvProcessSelection" HorizontalAlignment="Left" Height="93" Margin="10,30,0,0" VerticalAlignment="Top" Width="235" BorderThickness="0" SelectionChanged="lvProcessSelection_SelectionChanged">
<ListViewItem Name="itmERA" Content="Expense Reserve Automation"/>
<ListViewItem Name="itmFCS" Content="Financial Close Status"/>
<ListViewItem Name="itmPEL" Content="Peel"/>
</ListView>
</Grid>
</Border>
<ContentControl DataContext="{Binding Properties}" Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate" Value="{StaticResource ERAFileSelect}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedProcess}" Value="Expense Reserve Automation">
<Setter Property="ContentTemplate" Value="{StaticResource ERAFileSelect}" />
</DataTrigger>
<DataTrigger Binding="{Binding SelectedProcess}" Value="Financial Close Status">
<Setter Property="ContentTemplate" Value="{StaticResource FCSFileSelect}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
ViewModel Code is
public class MainWindowModel
{
public ApplicationRunTime AppRunTime { get; set; }
public LogMessage Progress { get; set; }
public MainWindowProperties Properties { get; set; }
public MainWindowModel()
{
AppRunTime = new ApplicationRunTime();
Progress = new LogMessage();
Properties = new MainWindowProperties();
Properties.StartButtonEnabled = false;
}
}
With the MainWindowProperties class
public class MainWindowProperties
{
public bool StartButtonEnabled { get; set; }
public string SelectedProcess { get; set; }
}
And within my MainWindow Constructor I have set the DataContext
mainWindowModel = new MainWindowModel();
this.DataContext = mainWindowModel;
When the selection from lvProcessSelection is changed the following code is executed
if (lvProcessSelection.SelectedItems.Count > 0)
{
mainWindowModel.Properties.SelectedProcess = ((ListViewItem)lvProcessSelection.SelectedItem).Content.ToString();
}
else
{
mainWindowModel.Properties.SelectedProcess = string.Empty;
}
This will update SelectedProcess within my ViewModel with either "Expense Reserve Automation" or "Financial Close Status"
I know the DataContext is set correctly for my ViewModel (but may not be for the ContentControl) as I am able to update lbxProgress with new messages and update txtRunTime with the application RunTime
However when I change the selection on lvProcessSelection nothing happens; the default controls of ERAFileSelect remains.
Could anybody point me in the right direction on how to solve this?
Could anybody point me in the right direction on how to solve this?
Your MainWindowProperties class should implement the INotifyPropertyChanged interface and raise change notifications whenever the SelectedProcess property is set to a new value:
public class MainWindowProperties : INotifyPropertyChanged
{
public bool StartButtonEnabled { get; set; }
private string _selectedProcess;
public string SelectedProcess
{
get { return _selectedProcess; }
set { _selectedProcess = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Please refer to MSDN for more information about this common interface: https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx
Every view model/model that you bind to must implement this interface and raise change notifications for any target value in the view to be updated.
Why you are not using Data template? Data template will work in this scenario.
I have listview with binding:
<ListView x:Name="OrdersListView" IsItemClickEnabled="True" SelectionMode="Single"
ItemClick="OrdersListView_ItemClick" SelectedItem="{Binding AllRoundsSelectedItem, Mode=TwoWay}">
I need to click element and receive data.
I do it like this.
public RootObject allRoundsSelectedItem;
public RootObject AllRoundsSelectedItem
{
get { return allRoundsSelectedItem; }
set { allRoundsSelectedItem = value; OnPropertyChanged();}
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void OrdersListView_ItemClick(object sender, ItemClickEventArgs e)
{
}
When i set breakpoint on this row set { allRoundsSelectedItem = value; OnPropertyChanged();}
I see that I have value that I need to have.
I try to enter data in another ListView.
Here code for it:
<ScrollViewer HorizontalAlignment="Left" Height="667" Margin="415,54,-124,-1" VerticalAlignment="Top" Width="989">
<ListView x:Name="DetailsListView" ItemsSource="{Binding AllRoundsSelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Height="667" Width="989">
<Grid x:Name="DetailGrid" Height="667" Width="989" VerticalAlignment="Top" >
<Grid HorizontalAlignment="Left" Height="44" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock1" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Время и дата заказа" VerticalAlignment="Top" Height="44" Width="214" FontSize="23"/>
<TextBlock x:Name="textBlock2" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding date_created}" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,44,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock3" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Статус" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock4" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding status }" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,88,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock5" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Осталось времени" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock6" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,132,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock7" HorizontalAlignment="Left" TextWrapping="Wrap" Text="На когда" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock8" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding billing.city}" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,176,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock9" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Сумма" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock10" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding total}" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,220,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock11" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Имя" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock12" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding billing.first_name}" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,264,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock13" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Телефон" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock14" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding billing.phone}" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,308,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock15" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Адрес" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock16" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding billing.address_1}" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,352,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock17" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Количество персон" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock18" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="{Binding billing.postcode}" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,396,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock19" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Откуда" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock20" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,440,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock21" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Состав заказа" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock22" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,484,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock23" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Приметка для кухни" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock24" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="44" Margin="0,528,0,0" VerticalAlignment="Top" Width="989" BorderBrush="#FFFBF8F8" BorderThickness="0,0,1,1">
<TextBlock x:Name="textBlock25" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Приметка для курьера" VerticalAlignment="Top" Height="44" Width="360" FontSize="23"/>
<TextBlock x:Name="textBlock26" HorizontalAlignment="Left" Margin="500,0,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="44" Width="360"/>
</Grid>
</Grid>
</StackPanel></DataTemplate></ListView.ItemTemplate></ListView>
But anything shows.
Where is my trouble?
Thank's for help so much!
Your question wasn't very clear, so I can only guess as to what you were trying to achieve. It looks as though you want some kind of master-detail interface, wherein you choose an item from the list (master) and then another form displays with controls for editing the data for that item (detail).
Your first ListView looks fine (and the binding works as you said). But why are you using another ListView for displaying the details of the selected item? ListViews are for displaying lists of data, but it appears that RootObject is not an array or collection class (I could be wrong, I don't know the class definition). You probably shouldn't be using a ListView, but whatever you use, you should bind the AllRoundsSelectedItem to the DataSource property of the panel.
Solution 1: I mostly agree with #Decade Moon, but for the last line, there is no DataSource property of the StackPanel you used, I think this maybe is a typo, it should be DataContext. Anyway, here I'm writing this answer to give a demo for this solution:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView x:Name="OrdersListView" IsItemClickEnabled="True" SelectionMode="Single"
ItemClick="OrdersListView_ItemClick" SelectedItem="{Binding AllRoundsSelectedItem, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ItemName}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ScrollViewer Grid.Column="1">
<StackPanel x:Name="Detail" Grid.Column="1" >
<TextBlock Text="{Binding ItemName}" FontSize="30" Foreground="Red" />
<TextBlock Text="{Binding Paramether1}" Margin="0,15" FontSize="20" />
<TextBlock Text="{Binding Paramether2}" FontSize="20" />
<TextBlock Text="{Binding Paramether3}" Margin="0,15" FontSize="20" />
<TextBlock Text="{Binding Paramether4}" FontSize="20" />
<TextBlock Text="{Binding Paramether5}" Margin="0,15" FontSize="20" />
</StackPanel>
</ScrollViewer>
</Grid>
If your layout is like this, then you can keep your most of the code in behind and in the OrdersListView_ItemClick event code like this:
private void OrdersListView_ItemClick(object sender, ItemClickEventArgs e)
{
AllRoundsSelectedItem = e.ClickedItem as RootObject;
Detail.DataContext = AllRoundsSelectedItem;
}
Solution 2: if you still want to use a ListView to show the details so can they be selected or something else, you can for example code like this:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView x:Name="OrdersListView" IsItemClickEnabled="True" SelectionMode="Single"
ItemClick="OrdersListView_ItemClick" SelectedItem="{Binding AllRoundsSelectedItem, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ItemName}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView x:Name="DetailsListView" ItemsSource="{Binding AllRoundsSelectedItem}" Grid.Column="1">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}" FontSize="20" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
And the type of AllRoundsSelectedItem should be List or OberservableCollection, it means you need to modify your code behind for example like this:
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
public MainPage ()
{
this.InitializeComponent();
this.DataContext = this;
}
private ObservableCollection<RootObject> collection = new ObservableCollection<RootObject>();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
for (int i = 0; i < 100; i++)
{
collection.Add(new RootObject
{
ItemName = "Item " + i,
Paramether1 = "Paramether1 " + i,
Paramether2 = "Paramether2 " + i,
Paramether3 = "Paramether3 " + i,
Paramether4 = "Paramether4 " + i,
Paramether5 = "Paramether5 " + i,
});
}
OrdersListView.ItemsSource = collection;
}
public ObservableCollection<string> allRoundsSelectedItem;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<string> AllRoundsSelectedItem
{
get { return allRoundsSelectedItem; }
set
{
allRoundsSelectedItem = value;
OnPropertyChanged();
}
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void OrdersListView_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as RootObject;
AllRoundsSelectedItem = new ObservableCollection<string>
{
item.ItemName,item.Paramether1,
item.Paramether2, item.Paramether3,
item.Paramether4, item.Paramether5,
};
}
}
By my side the RootObject class is like this:
public class RootObject
{
public string ItemName { get; set; }
public string Paramether1 { get; set; }
public string Paramether2 { get; set; }
public string Paramether3 { get; set; }
public string Paramether4 { get; set; }
public string Paramether5 { get; set; }
}
There are maybe other solutions, but you will need either modify your xaml code or the data type of your AllRoundsSelectedItem.
I have a ListBox which I add items to. Each time i select an item which is an object of a Person this person properties should be showed in textboxes. This person have person properties like age, name, sex and so on.
my listbox selection changed event only triggers one time or on new added items. It doesn't trigger when i click and an that is not just added.
Mainwindow.xaml.cs
namespace GUI_WPF_Eksamen
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Backlog bl = new Backlog();
public MainWindow()
{
InitializeComponent();
DataContext = bl;
this.PriorityComboBox.Items.Add("High");
this.PriorityComboBox.Items.Add("Medium");
this.PriorityComboBox.Items.Add("Low");
}
private void AddToProductBackLogBtn_Click(object sender, RoutedEventArgs e)
{
this.ProductBacklogList.Items.Add(bl);
this.NameTextBox.Text = String.Empty;
}
private void ProductBacklogList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = this.ProductBacklogList.SelectedItem as Backlog;
this.NameLabel.Content = item.NAME;
this.DescriptionTextBlock.Text = item.DESCRIPTION;
this.PriorityLabel.Content = item.PRIORITY;
this.TimeLabel.Content = item.TIME;
}
private void AddToSprint_Click(object sender, RoutedEventArgs e)
{
var currentItem = this.ProductBacklogList.SelectedItem as Backlog;
this.SprintBacklogList.Items.Add(currentItem);
}
}
}
Mainwindow.xaml
<Window x:Class="GUI_WPF_Eksamen.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GUI_WPF_Eksamen"
Title="GUI WPF application" Height="800" Width="1200">
<Window.Background>
<ImageBrush ImageSource="Images/chalkboard.jpg"/>
</Window.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="69*"/>
<RowDefinition Height="700*"/>
</Grid.RowDefinitions>
<Label x:Name="Title" Content="SCRUM-BOARD XXL" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Margin="15,10,5,0" VerticalAlignment="Top" Width="1172" Height="56" FontSize="36" FontStyle="Italic" FontWeight="Bold" Foreground="White"/>
<Grid HorizontalAlignment="Left" Height="680" Margin="15,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="354">
<Grid.RowDefinitions>
<RowDefinition Height="94*"/>
<RowDefinition Height="44*"/>
<RowDefinition Height="131*"/>
<RowDefinition Height="53*"/>
<RowDefinition Height="40*"/>
<RowDefinition Height="46*"/>
<RowDefinition Height="272*"/>
</Grid.RowDefinitions>
<Label Content="Navn" HorizontalAlignment="Left" Margin="0,44,0,0" VerticalAlignment="Top" Width="77" FontSize="16" Foreground="White"/>
<Label Content="Beskrivelse
" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Foreground="White" FontSize="16" Height="31" Grid.Row="1"/>
<Label Content="Prioritet" HorizontalAlignment="Left" Margin="0,7,0,0" VerticalAlignment="Top" Width="67" FontSize="16" Foreground="White" Grid.Row="3"/>
<Label Content="Estimeret tidsforbrug" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Foreground="White" FontSize="16" Grid.Row="4" Grid.RowSpan="2"/>
<TextBox x:Name="NameTextBox" HorizontalAlignment="Left" Height="23" Margin="51,52,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="303" Opacity="0.5" Text="{Binding Path=NAME}"/>
<ComboBox x:Name="PriorityComboBox" HorizontalAlignment="Left" Margin="73,12,0,0" VerticalAlignment="Top" Width="152" RenderTransformOrigin="0.5,0.5" Opacity="0.5" Grid.Row="3" SelectedItem="{Binding Path=PRIORITY}">
<ComboBox.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0.036"/>
<TranslateTransform/>
</TransformGroup>
</ComboBox.RenderTransform>
</ComboBox>
<TextBox x:Name="TimeTextBox" HorizontalAlignment="Left" Height="23" Margin="0,6,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="204" Opacity="0.5" Grid.Row="5" Text="{Binding Path=TIME}"/>
<Label Content="time(r)" HorizontalAlignment="Left" Margin="209,38,0,0" VerticalAlignment="Top" Foreground="White" FontSize="16" Width="57" Grid.Row="4" Grid.RowSpan="2"/>
<TextBox x:Name="DescriptionTextBox" HorizontalAlignment="Left" Height="111" Margin="0,10,0,0" Grid.Row="2" TextWrapping="Wrap" VerticalAlignment="Top" Width="354" Opacity="0.5" Text="{Binding Path=DESCRIPTION}"/>
<Button x:Name="AddToProductBackLogBtn" Content="Add Backlog item" HorizontalAlignment="Left" Grid.Row="6" VerticalAlignment="Top" Width="200" Height="27" Margin="66,0,0,0" Background="White" Opacity="0.7" Click="AddToProductBackLogBtn_Click"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="680" Margin="374,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="808" RenderTransformOrigin="0.459,0.431">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="79*"/>
<ColumnDefinition Width="47*"/>
<ColumnDefinition Width="76*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="209*"/>
<RowDefinition Height="131*"/>
</Grid.RowDefinitions>
<Label Content="Navn" HorizontalAlignment="Left" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" FontSize="16" Foreground="White" Height="31" Width="47"/>
<Label Content="Beskrivelse" HorizontalAlignment="Left" Margin="10,55,0,0" Grid.Row="1" VerticalAlignment="Top" Foreground="White" FontSize="16" Height="31" Width="87"/>
<Label Content="Prioritet
" HorizontalAlignment="Left" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" Foreground="White" FontSize="16" Height="32" Grid.Column="1" Width="66"/>
<Label Content="Estimeret tidsforbrug" Grid.Column="1" HorizontalAlignment="Left" Margin="10,55,0,0" Grid.Row="1" VerticalAlignment="Top" Foreground="White" FontSize="16" Height="31" Width="159"/>
<Label x:Name="PriorityLabel" Content="" Grid.Column="1" HorizontalAlignment="Left" Margin="90,10,0,0" Grid.Row="1" VerticalAlignment="Top" FontSize="16" Foreground="White" Width="79" Height="31"/>
<Label x:Name="TimeLabel" Grid.Column="2" HorizontalAlignment="Left" Margin="10,55,0,0" Grid.Row="1" VerticalAlignment="Top" Foreground="White" FontSize="16" Width="208" Height="31"/>
<ListBox x:Name="ProductBacklogList" HorizontalAlignment="Left" Height="353" Margin="10,55,0,0" VerticalAlignment="Top" Width="292" DisplayMemberPath="NAME" Opacity="0.505" SelectionChanged="ProductBacklogList_SelectionChanged" RenderTransformOrigin="0.5,0.5">
<ListBox.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform AngleY="-0.195"/>
<RotateTransform/>
<TranslateTransform Y="-0.497"/>
</TransformGroup>
</ListBox.RenderTransform>
</ListBox>
<ListBox x:Name="SprintBacklogList" HorizontalAlignment="Left" Height="353" Margin="10,55,0,0" VerticalAlignment="Top" Width="284" DisplayMemberPath="NAME" Grid.Column="2" Opacity="0.5"/>
<Label x:Name="NameLabel" HorizontalAlignment="Left" Margin="62,14,0,0" Grid.Row="1" VerticalAlignment="Top" Width="244" Height="27" Content="{Binding Path=NAME}" Foreground="White"/>
<Button x:Name="AddToSprint" Content="Add >>" Grid.Column="1" HorizontalAlignment="Left" Margin="54,201,0,0" VerticalAlignment="Top" Width="75" Height="20" Opacity="0.7" Click="AddToSprint_Click"/>
<TextBlock x:Name="DescriptionTextBlock" HorizontalAlignment="Left" Margin="10,86,0,0" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" Height="166" Width="296" Foreground="White"/>
</Grid>
</Grid>
That way of selection changed can be accomplished easily:
Have a look here:
<Window x:Class="ListBoxSelection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<ListBox ItemsSource="{Binding persons}" IsSynchronizedWithCurrentItem="True" DockPanel.Dock="Top">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="5,0"/>
<TextBlock Text="{Binding Age, StringFormat=is {0} years old}" Margin="5,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Orientation="Horizontal" DataContext="{Binding persons}" DockPanel.Dock="Top">
<TextBlock Text="You have selected: " FontWeight="SemiBold"/>
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
Margin="5,0"
FontWeight="SemiBold"
VerticalAlignment="Top"
HorizontalAlignment="Center"/>
<TextBox Text="{Binding Age, UpdateSourceTrigger=PropertyChanged}"
Margin="5,0"
FontWeight="SemiBold"
VerticalAlignment="Top"
HorizontalAlignment="Left"/>
</StackPanel>
<Button Content="Add Item" DockPanel.Dock="Top" Width="60" VerticalAlignment="Top" Margin="20" Click="btnAddItem_Click"/>
</DockPanel>
Note this down: IsSynchronizedWithCurrentItem="True"
From MSDN:
Gets or sets a value that indicates whether a Selector should keep the
SelectedItem synchronized with the current item in the Items property.
What's the next step? Display the selected item:
<StackPanel DataContext="{Binding persons}"/>
StackPanel is not an ItemsControl, it will not try to display all the items in persons but instead it will look for the selected one.
The ICollectionView interface contains a member called CurrentItem. What the IsSynchronizedWithCurrentItem does is: whenever an item is clicked on the ItemsControl, it sets the CurrentItem for the collection view. The ICollectionView also has two events: CurrentItemChanging and CurrentItemChanged. When the IsSynchronizedWithCurrentItem property is set, the ItemsControl will update the SelectedItem based on what the ICollectionView's CurrentItem is.
Further more, using UpdateSourceTrigger=PropertyChanged you will be able to update you selected item and this will be immediately displayed in the ListBox.
OK, that's about, here is the rest of the code:
public class Person : INotifyPropertyChanged
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
private int _Age;
public int Age
{
get { return _Age; }
set
{
_Age = value;
PropertyChanged(this, new PropertyChangedEventArgs("Age"));
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
And the codebehind:
public partial class MainWindow : Window
{
public ObservableCollection<Person> persons { get; set; }
public Person SelectedPerson
{
get { return (Person)GetValue(SelectedPersonProperty); }
set { SetValue(SelectedPersonProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedPerson. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedPersonProperty =
DependencyProperty.Register("SelectedPerson", typeof(Person), typeof(MainWindow), new PropertyMetadata(null));
public MainWindow()
{
InitializeComponent();
persons = new ObservableCollection<Person>();
persons.Add(new Person() { Name = "Name1", Age = 20 });
persons.Add(new Person() { Name = "Name2", Age = 25 });
persons.Add(new Person() { Name = "Name3", Age = 30 });
this.DataContext = this;
}
private void btnAddItem_Click(object sender, RoutedEventArgs e)
{
persons.Add(new Person() { Name = "NameAdded", Age = 50 });
}
}
As you see, your SelectionChanged handler is not needed anymore.
You may be asking, what is that SelectedPerson in the code behind:
Add this binding on the ListBox:
SelectedItem="{Binding SelectedPerson}"
And in that AddToSprint_Click use the SelectedPerson to get the Person instead of directly accessing the ListBox.
I am trying to use a dataGrid in WPF with c#. But I cannot get my datagrid to show any of my data in the table when I run my program in debug mode. I have this code executing when the datagrid loads. But all I see is an empty square.
private void dataGrid1_Loaded(object sender, RoutedEventArgs e)
{
var items = new List<SaveTable>();
items.Add(new SaveTable("A" , 0));
items.Add(new SaveTable("B" , 0));
items.Add(new SaveTable("C" , 0));
items.Add(new SaveTable("D" , 0));
items.Add(new SaveTable("E" , 0));
var grid = sender as DataGrid;
grid.ItemsSource = items;
}
I save a class named SaveTable which looks like this:
class SaveTable
{
public string Name { get; set; }
public double Value { get; set; }
public SaveTable(string name, double value)
{
this.Name = name;
this.Value = value;
}
}
I got this code format online and it seems like everything is right? any suggestions?
here is the xaml code for that window
<Window x:Class="RobustCalculator.Storage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Storage" Height="499" Width="546" Activated="Window_Activated" Loaded="Window_Loaded">
<Grid>
<TextBlock Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBlock1" Text="A" VerticalAlignment="Top" />
<TextBox HorizontalAlignment="Left" Margin="24,10,0,306" Name="valueA" Width="120" TextChanged="valueA_TextChanged" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="24,39,0,0" Name="valueB" VerticalAlignment="Top" Width="120" TextChanged="valueB_TextChanged" />
<TextBlock Height="20" HorizontalAlignment="Left" Margin="10,42,0,0" Name="textBlock2" Text="B" VerticalAlignment="Top" Width="20" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="24,71,0,0" Name="valueC" VerticalAlignment="Top" Width="120" TextChanged="valueC_TextChanged" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="10,72,0,0" Name="textBlock3" Text="C" VerticalAlignment="Top" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="10,101,0,0" Name="textBlock4" Text="D" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="24,98,0,0" Name="valueD" VerticalAlignment="Top" Width="120" TextChanged="valueD_TextChanged" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="24,130,0,0" Name="valueE" VerticalAlignment="Top" Width="120" TextChanged="valueE_TextChanged" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="11,131,0,0" Name="textBlock5" Text="E" VerticalAlignment="Top" />
<DataGrid AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" Margin="235,130,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="200" SelectionChanged="dataGrid1_SelectionChanged" Loaded="dataGrid1_Loaded" />
</Grid>
I added a breakpoint and the code isn't being executed. I am using the Loaded event, should I be using a different event?
Your code works fine with Loaded event but at the moment you set AutoGenerateColumns="False" and don't define columns. You need to either define columns manually
<DataGrid AutoGenerateColumns="False" ... Loaded="dataGrid1_Loaded">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
<DataGridTextColumn Binding="{Binding Value}" Header="Value"/>
</DataGrid.Columns>
</DataGrid>
or let it auto generate columns
<DataGrid AutoGenerateColumns="True" ... Loaded="dataGrid1_Loaded"/>