WPF Cascading Combobox to TextBox - c#

I'm new to Programming and have some difficulties with cascading ComboBox to TextBox. Hire is my code:
MainWindow.xaml
Window x:Class="WpfApplication26.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">
<Grid Margin="0,0,0,-1">
<ComboBox x:Name="Category" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" SelectionChanged="Category_SelectionChanged" Margin="309,52,0,0">
<ListBoxItem Name="clComboBoxItem1" Content="Comedy" Height="25"/>
<ListBoxItem Name="clComboBoxItem2" Content="Drama" Height="25"/>
<ListBoxItem Name="clComboBoxItem3" Content="Science Fisction" Height="25"/>
</ComboBox>
<ComboBox x:Name="Shows" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="309,79,0,0" SelectionChanged="Shows_SelectionChanged" />
<TextBox x:Name="TextBox1" HorizontalAlignment="Left" Height="23" Margin="309,106,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
</Grid>
MainWindow.xamlcs
namespace WpfApplication26
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Category_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//Create List for Comedy selection
List<fruits> dropDownList_Comedy = new List<fruits>();
dropDownList_Comedy.Add(new fruits() { price = 10, Name = "Apples" });
dropDownList_Comedy.Add(new fruits() { price = 9, Name = "Bammamas" });
dropDownList_Comedy.Add(new fruits() { price = 1, Name = "Mango" });
//Create List for Drama selection
List<fruits> dropDownList_Drama = new List<fruits>();
dropDownList_Drama.Add(new fruits() { price = 10, Name = "Liver"});
//Create List for Science Fiction selection
List<fruits> dropDownList_SciFi = new List<fruits>();
dropDownList_SciFi.Add(new fruits() { price = 10, Name = "Apples2" });
//Check for SelectedIndex value and assign appropriate list to 2nd
if (Category.SelectedIndex == 0)
{
Shows.ItemsSource = dropDownList_Comedy;
Shows.DisplayMemberPath = "Name";
}
else if (Category.SelectedIndex == 1)
{
Shows.ItemsSource = dropDownList_Drama;
Shows.DisplayMemberPath = "Name";
}
else if (Category.SelectedIndex == 2)
{
Shows.ItemsSource = dropDownList_SciFi;
Shows.DisplayMemberPath = "Name";
}
{
}
}
private void Shows_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
{
fruits dropDownList_Comedy = Shows.SelectedItem as fruits ;
TextBox1.Text = Convert.ToString(dropDownList_Comedy.price);
}
{
fruits dropDownList_Drama = Shows.SelectedItem as fruits;
TextBox1.Text = Convert.ToString(dropDownList_Drama.price);
}
{
fruits dropDownList_SciFi = Shows.SelectedItem as fruits;
TextBox1.Text = Convert.ToString(dropDownList_SciFi.price);
}
}
}
}
Class1.cs
class fruits
{
public int price { get; set; }
public string Name { get; set; }
}
}
There is problem with System.NullReferenceException. I dont know what to do with it. Thanks for helping.

You're using SelectedValue instead of SelectedItem in your second block in the Shows_SelectionChanged function.
SelectedValue returns a String, which can't be parsed into a fruits (so it'll return null). And you're trying to access a member of null when using null.price, so it raises a NullReferenceException.
Edit
If you only want to display the SelectedItem of a ListBox in a TextBlock you can do:
<ListBox x:Name="MyListBox">
...
</ListBox>
<TextBox Text="{Binding ElementName=MyListBox,
Path=SelectedItem,
TargetNullValue=Nothing is selected,
Mode=OneWay}"/>
You don't need code behind in this case.

Related

How to clear a ComboBox after research WPF?

I had a research by criteria with Two combobox, it works fine
after the research is finished, I have a button Display All : to reset the combobox to null..and the DataGrid display with all elements ,
The problem that the combobox must be empty when I click on the Button Dispaly All!
Without select an element in combobox(just dispaly the datagrid):I have 6 elements in the datagrid, it is correct..and the combobox are Empty
After select the Search criteria, i have the result correct: (I have just 3 results, it is the correct action)
3 elements picture
When I click on the button Display All:(I have all the elements in datagrid, 6 elements..It is correct) But the Combobox aren't empty!!
6 elements picture
The view:
<Window x:Class="WPFAuthentification.Views.BusinesseventsView"
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" >
<Label Content="Entity Type" Width="128" Grid.Row="1" Grid.ColumnSpan="2"/>
<ComboBox HorizontalAlignment="Center" VerticalAlignment="Center"
ItemsSource="{Binding EntityLevelEnum}"
SelectedItem="{Binding EntityType, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True, TargetNullValue=''}"
Grid.ColumnSpan="2" Grid.Column="1" />
<Button Content="Dislplay all" ToolTip="Display All Business Events"
VerticalAlignment="Top" Command="{Binding Initialize}"
Visibility="{Binding Path=ShowDisplayAllButton, Converter={StaticResource BoolToVis}}" />
<DataGrid ..... />
</Window>
The ViewModel:
class BusinesseventsViewModel : ViewModelBase1
{
private ObservableCollection<BusinessEventClass> businessEventsList;
private RelayCommand<string> initialize;
public RelayCommand<string> Initialize
{
get { return initialize; }
}
public BusinesseventsViewModel()
{
//businessEventsList: to Get all the Business events
businessEventsList = new ObservableCollection<BusinessEventClass>(WCFclient.getAllBusinessEvent());
//Enumeration of Entity Type and Criticality
levelCriticalityEnum = new ObservableCollection<Level_Criticality>(Enum.GetValues(typeof(Level_Criticality)).Cast<Level_Criticality>());
entityLevelEnum = new ObservableCollection<BusinessEntityLevel>(Enum.GetValues(typeof(BusinessEntityLevel)).Cast<BusinessEntityLevel>());
//the Button Display All :
initialize = new RelayCommand<string>(initFunc);
}
//Function of the Button Display All
private void initFunc(object obj)
{
EntityType = null;
OnPropertyChanged("EntityLevelEnum");
Criticality = null;
OnPropertyChanged("Criticality");
}
private string entityType;
public string EntityType
{
get { return entityType; }
set
{
entityType = value;
businessEventsList = filterByCriteria(entityType, criticality);
OnPropertyChanged("BusinessEventsList");
OnPropertyChanged("EntityType");
}
}
//Function of the research :
public ObservableCollection<BusinessEventClass> filterByCriteria(string entityType, string criticality)
{
BusinessEventsList = new ObservableCollection<BusinessEventClass>(WCFclient.getAllBusinessEvent());
ObservableCollection<BusinessEventClass> updatedList = new ObservableCollection<BusinessEventClass>();
if ((entityType == null) && (Criticality == null))
{
updatedList = businessEventsList;
}
if ((entityType != null && entityType != "") && (Criticality != null))
{
updatedList = new ObservableCollection<BusinessEventClass>(BusinessEventsList.Where(a => a.EntityType.ToString().ToLower().Equals(criticality.ToString())
&& a.Critciality.ToString().Equals(criticality.ToString())));
}
}
There must be something wrong with your implementation of the INotifyPropertyChanged interface.
Using GalaSoft.MvvmLight I did this, and works without problem;
Window.cs content:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new TestViewModel();
}
}
public class TestViewModel : ViewModelBase
{
private string _selectedItem;
public RelayCommand Command { get; }
public ObservableCollection<string> ItemsSource { get; }
public string SelectedItem
{
get { return _selectedItem; }
set { Set(ref _selectedItem, value); }
}
public TestViewModel()
{
Command = new RelayCommand(() => SelectedItem = null);
ItemsSource = new ObservableCollection<string> { "index 0", "index 1", "index 2", "index 3" };
}
}
and my Window.xaml content
<Window.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type testClean:TestViewModel}">
<Grid>
<Viewbox>
<TextBlock Foreground="HotPink">just some pink text</TextBlock>
</Viewbox>
<ComboBox Height="50" Width="200" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="20" SelectedIndex="0"
ItemsSource="{Binding ItemsSource}"
SelectedItem="{Binding SelectedItem}"/>
<Button Command="{Binding Command}" Height="50" Width="100" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="250,20,20,20">Reset</Button>
</Grid>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
<ContentControl Content="{Binding}" />
Tested and working as expected (when you put null as SelectedItem the combobox returns empty)

Combobox in RowDetailTemplate update all before selected colums

I Have a Combobox in a RowdetailsTemplate in a Datagrid. If i switch the columns then automatic change the value in the Datagridcolumn with the before selected Value.
The Value in Datagrid column should only change if the value in the Combobox are changed
public class BMFill
{
public BMFill()
{
colCBArt.Add(new CBArt { Name = "test" , Nr = 0 });
colCBArt.Add(new CBArt { Name = "hallo", Nr = 1 });
colCBArt.Add(new CBArt { Name = "welt", Nr = 2 });
colCBArt.Add(new CBArt { Name = "blubb", Nr = 3 });
colCBArt.Add(new CBArt { Name = "lalalala", Nr = 4 });
}
List<CBArt> colCBArt = new List<CBArt>();
CollectionViewSource cvsCBArt = null;
public ICollectionView ViewCBArt
{
get
{
if (cvsCBArt == null) cvsCBArt = new CollectionViewSource() { Source = colCBArt };
return cvsCBArt.View;
}
}
public class CBArt
{
public string Name { get; set; }
public int Nr { get; set; }
}
}
<Window.Resources>
<local:BMFill x:Key="vm"/>
</Window.Resources>
<DataGrid x:Name="dg">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<ComboBox Margin="10,10,10,10" Grid.Column="1" Grid.Row="1"
SelectedValuePath="Nr"
SelectedValue="{Binding NrDG,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
ItemsSource="{Binding Source={StaticResource vm}, Path=ViewCBArt}"
/>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
i hope can understand my problem and can me help =)
You can try to add event handlers for DropDownOpened and DropDownClosed events, raise a flag while the dropdown is opened, and check if this flag is not raised while you change the value in the Datagridcolumn.
XAML:
<ComboBox Margin="10,10,10,10" Grid.Column="1" Grid.Row="1"
SelectedValuePath="Nr"
SelectedValue="{Binding NrDG,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
ItemsSource="{Binding Source={StaticResource vm}, Path=ViewCBArt}"
DropDownOpened="OnDropDownOpened" DropDownClosed="OnDropDownClosed"
/>
C#:
private bool _comboxBoxIsOpened = false;
private void OnDropDownOpened(object sender, EventArgs e)
{
_comboxBoxIsOpened = true;
}
private void OnDropDownClosed(object sender, EventArgs e)
{
_comboxBoxIsOpened = false;
}
SelectedValuePath="Nr"
SelectedValue="{Binding NrDG,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"
ItemsSource="{Binding Source={StaticResource vm}, Path=ViewCBArt}"
IsSynchronizedWithCurrentItem="False"
this Solution work by me

Comobox Windows 10 MVVM Light

I am trying to bind values to Combobox in a Windows 10 Universal App. I am using MVVM Light. I can bind all values properly except for Combo Box. The items are never shown. I am not sure what I am missing.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BigappleSP.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModels="using:BigappleSP.ViewModels"
x:Class="BigappleSP.Views.ContactusPage"
mc:Ignorable="d" DataContext="{Binding ContactusViewModdel, Source={StaticResource Locator}}">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<RelativePanel FlowDirection="LeftToRight" Height="640" VerticalAlignment="Bottom">
<TextBox x:Name="txtName" MinWidth="320"
PlaceholderText="Name" InputScope="PersonalFullName"
RelativePanel.AlignHorizontalCenterWithPanel="True"
Text="{Binding ContactusViewModel.Name, Mode=TwoWay}"
Margin="10,10"/>
<TextBox x:Name="txtEmail" MinWidth="320"
PlaceholderText="Email"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="txtName"
Margin="10,10"
Text="{Binding ContactusViewModel.Email, Mode=TwoWay}"
InputScope="EmailSmtpAddress" />
<TextBox x:Name="txtPhone" MinWidth="320"
PlaceholderText="Phone Number"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="txtEmail" Margin="10,10"
InputScope="TelephoneNumber"
Text="{Binding ContactusViewModel.PhoneNumber, Mode=TwoWay}"/>
<ComboBox x:Name="lstOptions" MinWidth="320" MinHeight="35"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="txtPhone" Margin="10,10"
ItemsSource="{Binding Path=ContactusViewModel.AvailableOptions, Mode=TwoWay}"
PlaceholderText="How can we help you"
IsSynchronizedWithCurrentItem="False"
DisplayMemberPath="Title">
</ComboBox>
<TextBox x:Name="txtMessage" MinWidth="320" MinHeight="150"
RelativePanel.AlignHorizontalCenterWithPanel="True"
RelativePanel.Below="lstOptions"
InputScope="Text" Margin="10,10"
Text="{Binding ContactusViewModel.Message, Mode=TwoWay}"/>
</RelativePanel>
</Grid>
View Model
public class ContactusViewModel : Template10.Mvvm.ViewModelBase
{
public string Name { get; set; }
public string Email { get; set; }
public int PhoneNumber { get; set; }
private ObservableCollection<Options> _options = new ObservableCollection<Models.Options>();
public ObservableCollection<Options> Options
{
get
{
if (_options == null || _options.Count <= 0)
{
_options.Add(new Options() { Id = 1, Title = "Development" });
_options.Add(new Options() { Id = 2, Title = "Training" });
_options.Add(new Options() { Id = 3, Title = "Consulting" });
}
return _options;
}
set
{
_options = value;
}
}
public string Message { get; set; }
// constructor
public ContactusViewModel()
{
_options.Add(new Options() { Id = 1, Title = "Development" });
_options.Add(new Options() { Id = 2, Title = "Training" });
_options.Add(new Options() { Id = 3, Title = "Consulting" });
// Options = _options;
}
public override void OnNavigatedTo(object parameter, NavigationMode mode, IDictionary<string, object> state)
{
base.OnNavigatedTo(parameter, mode, state);
}
}
I am using Options as observable collection to bind to Combo Box.
There is no AvailableOptions property on your view model, there is only Options.
You also need to have another property in the view model for the selected option, and bind it to the combo box's SelectedItem property.

Binding class to ListView data template

I am trying to bind a ListView with a Model List. The xaml is as -
<ListView Name="lvProductBinding" HorizontalAlignment="Left" Height="434" Margin="10,144,0,0" VerticalAlignment="Top" Width="909">
<ListView.ItemTemplate>
<DataTemplate>
<Expander Header="{Binding ProductNo}" HorizontalAlignment="Left" Margin="967,153,-912,0" VerticalAlignment="Top" Width="895" Height="224" IsExpanded="False">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Height="195" VerticalAlignment="Top" Width="895" Margin="0,0,-2,0">
<Label Content="{Binding ProductDescription}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="181" Height="27" />
<Label Content="{Binding VendorName}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="181" Height="27" />
</StackPanel>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In mu xaml.cs I am doing this inside the constructor -
List<ProductDetailsModel> products;
products = new List<ProductDetailsModel>();
ProductDetailsModel objProductDetailsModel = new ProductDetailsModel();
objProductDetailsModel.VendorProductInventory = new VendorProductInventory() { ProductNo = "XS-3487", ProductDescription = "Perfume", VendorName = "JohnDoe" };
products.Add(objProductDetailsModel);
objProductDetailsModel = new ProductDetailsModel();
objProductDetailsModel.VendorProductInventory = new VendorProductInventory() { ProductNo = "TT-23487", ProductDescription = "Shoes", VendorName = "Richard Gere" };
products.Add(objProductDetailsModel);
objProductDetailsModel = new ProductDetailsModel();
objProductDetailsModel.VendorProductInventory = new VendorProductInventory() { ProductNo = "VFG-33487", ProductDescription = "Socks", VendorName = "Tom Cruise" };
products.Add(objProductDetailsModel);
lvProductBinding.ItemsSource = products;
where the ProductDetailsModel class is defined as -
public class ProductDetailsModel : INotifyPropertyChanged
{
public ProductDetailsModel()
{
}
private VendorProductInventory _vendorProductInventory;
public VendorProductInventory VendorProductInventory
{
get
{
return _vendorProductInventory;
}
set
{
if (_vendorProductInventory != value)
{
_vendorProductInventory = value;
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, e);
}
}
}
Can someone please advise as to what I am doing wrong here.
Eagerly waiting for a reply.
Thanks,
Saket
There are several things wrong with the code you posted.
First, as Sheridan noted, your implementation of INotifyPropertyChanged is wrong, automatic updates to the data in the ListView won't work until it is correct.
Second, all of the bindings listed in your XAML file don't have matching public properties in the ProductDetailsModel class. More than likely your ListView is being populated and all the bindings are failing (you should see exceptions for this in the VS output window at runtime). Your bindings, as written, should look like:
{Binding Path=VendorProductInventory.ProductNo}

How to determine the clicked item in a gridview

I used this XAML code to create a gridview and add items to it:
<Grid x:Name="MainStack" HorizontalAlignment="Left" Height="628" Grid.Row="1" VerticalAlignment="Top" Width="1366">
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="130,42,116,46"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
Background="#FFFB0404" Margin="0,0,0,0" RenderTransformOrigin="0.489,0.503" ItemClick="MainPage_Click">
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
<x:String>Item 3</x:String>
<x:String>Item 4</x:String>
<x:String>Item 5</x:String>
<x:String>Item 6</x:String>
<x:String>Item 7</x:String>
<x:String>Item 8</x:String>
</GridView>
</Grid>
Then I tried using this C# code
private void MainPage_Click(object sender, ItemClickEventArgs e)
{
string output = e.ClickedItem.ToString();
int ClickValue = Convert.ToInt32(output);
if (ClickValue == 0)
{
this.Frame.Navigate(typeof(ItemsPageRSS));
}
}
to make the app navigate to a page when the 1st item is clicked but it gave an error.
Please if anyone can tell me how to isolate each iem and add a seperate click event for each and how to customize the gridview items by adding titles, subtitles and images to the items.
Thank you in advance.
Here I am giving you simple example if you can't understand MSDN sample. Just create new project and paste the whole code.
XAML
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<GridView
x:Name="itemGridView"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsItemClickEnabled="True"
Background="#FFFB0404"
ItemClick="MainPage_Click"/>
</Grid>
C#
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var gvData = new ObservableCollection<MyData>();
for (int i = 0; i < 8; i++)
{
gvData.Add(new MyData
{
ID = i,
Image = new BitmapImage(new Uri("ms-appx:///Assets/Logo.png")), //You can add any image
Title = "Title " + i,
Subtitle = "Subtitle " + i
});
}
itemGridView.ItemsSource = gvData;
}
private void MainPage_Click(object sender, ItemClickEventArgs e)
{
MyData output = e.ClickedItem as MyData;
int ClickValue = output.ID;
if (ClickValue == 0)
{
this.Frame.Navigate(typeof(ItemsPageRSS));
//TODO : Do whatever you want
}
//.....
//TODO : Do operations for other items as well.
}
You may create MyData class outside the scope of MainPage (XAML Page) class.
public class MyData
{
public int ID { get; set; }
public ImageSource Image { get; set; }
public string Title { get; set; }
public string Subtitle { get; set; }
}

Categories

Resources