I have a listBox that already populated by MySql table. I want to change the content of listBox anyway user pressing a button, what I done for this is to call sql class creator in my code with new query that filter the data from table, the problem is how to change listbox content in that button event handler?
here is my codes
private void shirtSelect_Click(object sender, RoutedEventArgs e)
{
string shirt = "SELECT * FROM viewermenu.grament where type = 'shirt'";
var shirtTable = new DatabaseTable();
string id = null;
shirtTable.GetTable(shirt, id);
listBox.DataContext = shirtTable;
}
and xaml side:
<ListBox x:Name="listBox" BorderBrush="Transparent" Background="Transparent" SelectionChanged="listBox_SelectionChanged" SelectionMode="Single" ItemsSource="{Binding Source={StaticResource NamesTable}}" it HorizontalContentAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" RenderTransformOrigin="0.5,0.5" Margin="0" Padding="0,0,0,317" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="200" Width="200" >
<Image Margin="3" Source="{Binding pic_path}" RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.EdgeMode="Aliased"/>
<TextBox Margin="3" Text="{Binding name}" Visibility="Visible"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and databbase table class:
public DataTable GetTable(String query, String sortBy)
{
String connString = "server=192.168.*.**;uid=*****;pwd=****;database=viewermenu";
connection = new MySqlConnection(connString);
adapter = new MySqlDataAdapter(query, connection);
DataTable dataTable = new DataTable();
adapter.Fill(dataTable);
dataTable.DefaultView.Sort = sortBy;
return dataTable;
}
}
Some mistakes in the given code, correct them and have a try.
1.Add IsItemsHost to the ItemsPanelTemplate:
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
2.Define a ShirtData class:
public class ShirtData
{
public string pic_path { get; set; }
public string name { get; set; }
public ShirtData(string path, string theName)
{
pic_path = path;
name = theName;
}
}
3.Set the ItemsSource in the code-behind (some pseudocode):
.......
var table = shirtTable.GetTable(shirt, id);
var shirts = new List<ShirtData>();
foreach (DataRow row in table.Rows)
{
var shirtData = new ShirtData(row["pic_path"].ToString(), row["name"].ToString());
shirts.Add(shirtData);
}
listBox.ItemsSource = shirts;
You need to amend the property that is bound to NamesTable below.
ItemsSource="{Binding Source={StaticResource NamesTable}}"
ie, assuming the property is a list, add and remove items as you would normally do with a list.
Related
I am working on a C# UWP assignment and I have a listview displaying information from a database. I want to show a list of orders, and each row has an orderID and a button to delete the order (which will delete it from the database). I though I could use a x:Name="orderid" and just pull that value in my function but it isn't recognizing it in the c# code.
.xaml.cs file includes:
Order o = new Order();
OrderList.ItemsSource = o.GetProducts(user);
.xaml (removed other columns for sake of example):
<RelativePanel Grid.Row="4" Grid.RowSpan="3" Grid.Column="0" Grid.ColumnSpan="7" HorizontalAlignment="Center">
<ListView Name="OrderList"
SelectionMode="Single"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.VerticalScrollMode="Enabled"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.IsHorizontalRailEnabled="True"
Margin="20">
<ListView.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="ID" Margin="8,0" Width="50" Foreground="DarkRed" />
<TextBlock Text="Date" Width="200" Foreground="DarkRed" />
<TextBlock Text="Delete" Width="50"/>
</StackPanel>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Order">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="orderid"
Text="{x:Bind OrderID}"
Width="50" />
<TextBlock Name="orderdate"
Text="{x:Bind OrderDate}"
Width="200" />
<Button Content="X" Click="Button_Click"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativePanel>
C# (Order Class - OrderID etc are all properties):
public ObservableCollection<Order> GetProducts(User user)
{
const string GetOrdersQuery = "select * from orders";
var orders = new ObservableCollection<Order>();
try
{
using (SqlConnection conn = new SqlConnection(user.ConnectionString))
{
conn.Open();
if (conn.State == System.Data.ConnectionState.Open)
{
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = GetOrdersQuery;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var order = new Order();
order.OrderID = (int)reader["orderID"];
order.OrderDate = (DateTime)reader["orderDate"];
order.MethodOfDelivery = (string)reader["methodOfDelivery"];
order.DeliveryAddress = (reader["deliveryAddress"] as string);
order.MethodOfPayment = (string)reader["methodOfPayment"];
order.CardUsed = (reader["cardNumber"] as string);
order.Subtotal = (decimal)reader["subtotal"];
order.Discount = (decimal)reader["discountPercentage"];
order.Tax = (decimal)reader["tax"];
order.OrderTotal = (decimal)reader["orderTotal"];
order.CustID = (reader["custID"] as int?) ?? 0;
orders.Add(order);
}
}
}
}
}
return orders;
}
catch (Exception eSql)
{
Debug.WriteLine("Exception: " + eSql.Message);
}
return null;
}
and then I wanted to make a function in the xaml.cs file that would grab that row's orderID, and make a query to delete the order based on the id, but doing orderid.Text won't work here for some reason.
Any suggestions/help would be much appreciated!
If my code is a little all over the place it's because I'm fairly new to this!
One possible solution is to bind the "OrderId" to the "Tag" attribute in your Button element.
<Button Content="X" Click="Button_Click" Tag="{Binding Id}"/>
After the bind, in your Event handler for Click you call a method to remove it from database and from your ObservableCollection, something like:
private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
var button = sender as Button;
_viewModel.DeleteOrder((int)button.Tag);
}
My DeleteOrder method is simple:
private ObservableCollection<Order> _orders;
public ObservableCollection<Order> Orders
{
get { return _orders; }
set { _orders = value; OnChange(); }
}
public void DeleteOrder(int id)
{
var order = Orders.FirstOrDefault(o => o.Id == id);
if (order != null)
{
Orders.Remove(order);
}
}
I'm new to using WPF forms, I have created a page that displays images from a database, but despite days of searching I cannot find a way of knowing which image has had a mouse over or mouse click event on it.
To setup the images I have:
public class RBimageData
{
private string _Title;
public string Title
{
get { return this._Title; }
set { this._Title = value; }
}
private BitmapImage _ImageData;
public BitmapImage ImageData
{
get { return this._ImageData; }
set { this._ImageData = value; }
}
private String _ImageID;
public String ImageID
{
get { return this._ImageID; }
set { this._ImageID = value; }
}
}
public MainWindow()
{
InitializeComponent();
RBpartsList rbPartsList = mongoDB.GetRBparts("elements", 1, 7); // get parts from database
List<RBpartsImages> rbImages = rbPartsList.RBparts;
List<RBimageData> md = new List<RBimageData>();
foreach (RBpartsImages img in rbImages)
{
RBimageData m = new RBimageData
{
Title = img.ImageFilename,
ImageID = "id_"+img.PartNum,
ImageData = LoadImage(rbPartsList.FilePath,img.ImageFilename) }; // provides BitmapImage URI for image
md.Add(m);
}
RBbox.ItemsSource = md.ToArray();
}
and the images are displayed in the XAML, I have used the Tag element to hold the ImageID:
<ListView x:Name="RBbox" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Height="143" Margin="10,0,10,10" Background="#FFE6E2E2">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="7" Rows="1" HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Border BorderThickness="1" BorderBrush="#FF000000" VerticalAlignment="Top" HorizontalAlignment="Left" Width="100" Height="100" Background="#FFC1A0A0">
<Button
MouseEnter="IdentifyPartImage_MouseEnter"
MouseLeave="IdentifyPartImage_MouseLeave" >
<Image Source="{Binding ImageData}"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
Stretch="UniformToFill"
Tag="{Binding ImageID}"/>
</Button>
</Border>
<TextBlock Text="{Binding Title}" HorizontalAlignment="Center" VerticalAlignment="Top" Width="100" Height="14" FontSize="10" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
but in my codebehind the this.Tag is always null:
private void IdentifyPartImage_MouseEnter(object sender, MouseEventArgs e)
{
// this fails - tag is null
var imgId = this.Tag.ToString();
Debug.WriteLine("id: {0}, {1}", "imageID", imgId.ToString());
}
It won't work with x:Name="{Binding ImageID}".. I can't find anything that will let me identify which image has been clicked, can you help?
Thanks.
When you reference this in your code-behind, it points to the Window object. You are looking for the Tag property of the Image control.
For that I recommend defining the MouseEnter="IdentifyPartImage_MouseEnter" and MouseLeave="IdentifyPartImage_MouseLeave" events on the Image control, and then the sender parameter will be that Image object.
In your XAML:
<Button>
<Image Source="{Binding ImageData}"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Stretch="UniformToFill"
Tag="{Binding ImageID}"
MouseEnter="IdentifyPartImage_MouseEnter"
MouseLeave="IdentifyPartImage_MouseLeave"/>
</Button>
And in your code-behind:
private void IdentifyPartImage_MouseEnter(object sender, MouseEventArgs e)
{
var imgId = ((Image)sender).Tag.ToString();
Debug.WriteLine("id: {0}, {1}", "imageID", imgId);
}
I have a ListView that is enclosed inside a dragablz tabs plugin:
<dragablz:TabablzControl Opacity="0.8" BorderBrush="#FF4C589C" Margin="10,49,10,10" Background="#FF402D61" TabStripPlacement="Left">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController />
</dragablz:TabablzControl.InterTabController>
<TabItem Header="Texts">
<WrapPanel x:Name="textContainer"/>
</TabItem>
<TabItem Header="Files">
<ListView SelectionMode="Extended" x:Name="files" Background="#FF19174B" AllowDrop="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled" PreviewMouseLeftButtonDown="files_PreviewMouseLeftButtonDown" MouseMove="files_MouseMove">
<ListView.DataContext>
<local:FileItem/>
</ListView.DataContext>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<local:FileItem/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</TabItem>
</dragablz:TabablzControl>
The caller window calls InitItems() method of the window containing this ListView populating it with user controls of type FileItem:
public int InitItems()
{
FileOps.UserDataCollection userData = Utility.userData;
if (userData != null && userData.userData != null && userData.userData.Count > 0)
{
foreach (UserData ud in userData.userData)
{
switch (ud.DataType)
{
case "file": _FileItems.Add(new FileItem(ud));
break;
default: break;
}
}
files.ItemsSource = FileItems;
}
return 0;
}
FileItems and _FileItems are defined as:
private ObservableCollection<FileItem> _FileItems = new ObservableCollection<FileItem>();
public ObservableCollection<FileItem> FileItems
{
get
{
return _FileItems;
}
}
Which are getting data successfully when checked using a breakpoint on line files.ItemsSource = FileItems; in InitItems() method.
But the problem is that the ListView is not showing the user controls. Please tell me what I am missing? I am just a beginner in WPF.
I am developing one Windows store application. I have implemented one listview. listview contains image , textblock and checkbox controls. my listview gets the data from internet i have done xml parsing with listview and binded data to listview. i want to get all the data from listview where checkboxes are checked in listview.
my xaml code is:
<ListView Name="display" ItemsSource="{Binding}" SelectionMode="Single"
SelectionChanged="display_SelectionChanged"
ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.HorizontalScrollBarVisibility="Visible"
ItemContainerStyle="{StaticResource ListViewItemStyle12}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel x:Name="stak2" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Image Source="{Binding Path=Image}" Width="450" Tapped="image_taped" />
<CheckBox Tag="{Binding Path=tag}" Visibility="{Binding Path=visichk}" Height="40" Name="addremove"
HorizontalAlignment="Center" Checked="add_checked" Unchecked="sub_checked" Opacity="0.5"
Background="White" VerticalAlignment="Top" Template="{StaticResource CheckboxImageTemplate}" >
</CheckBox>
<TextBlock Text="{Binding Image_code}" FontSize="25" Foreground="Gray" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
datasource for listview :
XDocument xmlDoc = XDocument.Parse(responseString);
var Categories = xmlDoc.Descendants("product").ToArray();
List<ProductData> displaylst = new List<ProductData>(); //ProductData is my Class.
foreach (var cat in Categories)
{
string prId = cat.Elements("id_products").Select(r => r.Value).FirstOrDefault();
List<string> Image = cat.Descendants("images").Elements("src").Attributes("largimage").Select(r => r.Value).ToList();
List<string> Image_code = cat.Descendants("images").Elements("src").Select(r => r.LastAttribute.Value).ToList();
int i = 0;
foreach (string img in Image)
{
displaylst.Add(new ProductData { Id = prId, Image = img, Image_code = Image_code[i] });
i++;
}
}
display.ItemsSource = displaylst;
Now on one button click i want to get the data of Product like prId,Image,Image_code where checkbox are checked from listview and put it into the simple list.
how can i did this please help me. thanks in advance.
First let's add a property to your ProductData class
public class ProductData
{
public string Id { get; set; }
public string Image { get; set; }
// I dont know exactly what's in this class
// ... more properties
// Add this one
public bool IsSelected { get; set; }
}
Now that we have a boolean IsSelected in our ProductData class we can know which are selected.
In the second foreach change this line
// Set IsSelected to false by default
displaylst.Add(new ProductData { IsSelected = false, Id = prId, Image = img, Image_code = Image_code[i] });
And bind the "IsChecked" property of your checkbox to IsSelected
<CheckBox IsChecked="{Binding Path=IsSelected}" Tag="{Binding Path=tag}" Visibility="{Binding Path=visichk}" Height="40" Name="addremove"
HorizontalAlignment="Center" Checked="add_checked" Unchecked="sub_checked" Opacity="0.5"
Background="White" VerticalAlignment="Top" Template="{StaticResource CheckboxImageTemplate}" >
With binding when you check one of the checkbox, the associed productData IsSelected property will become "true" automatically.
So now you just have to do a new list and select only ProductData where IsSelected is true:
List<ProductData> listOfSelectedProducts = (from product in displaylst
where product.IsSelected == true
select product).ToList();
Here you go you got a list of ProductData with only selected products.
I am populating an UniformGridwith binding. The source is a Square[,], and the UniformGridis filled with Button objects.
Here is what I did :
Data Binding between a double array and a grid
I get a System.InvalidOperationException when trying to do this :
private void OnClickButton(object sender, RoutedEventArgs e)
{
Button b = (Button)sender;
UniformGrid grid = ItemControlGrid.ItemsPanel.LoadContent() as UniformGrid;
int rows = grille.Rows;
int columns = grille.Columns;
UIElementCollection children = grid.Children; // I get the Exception here
int index = children.IndexOf(b);
int row = index / columns;
int column = index % rows;
}
Here is my XAML :
<ItemsControl Background="Gray" Margin="0" Width="800" Height="800"
x:Name="ItemControlGrid"
ItemsSource="{Binding MapGrid}"
ItemTemplateSelector="{StaticResource selector}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid
IsItemsHost="true"
x:Name="My_UniformGrid" Rows="25" Columns="25"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Why do I get this Exception?
Change the line where you get an exception to:
ItemCollection children = ItemControlGrid.Items;
The rest of the code should compile just as fine. I assume that grille is actually grid.
<ItemsControl Background="Gray" Margin="0" Width="800" Height="800"
x:Name="ItemControlGrid">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid IsItemsHost="true" Rows="25" Columns="25"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- First two elements are just dummies to test the result-->
<Control />
<Image />
<Button Click="Button_Click_1" />
</ItemsControl>
Codebehind:
void Button_Click_1(object sender, RoutedEventArgs e)
{
var b = (Button) sender;
var grid = ItemControlGrid.ItemsPanel.LoadContent() as UniformGrid;
var rows = grid.Rows;
var columns = grid.Columns;
var children = ItemControlGrid.Items;
var index = children.IndexOf(b);
var row = index/columns;
var column = index%rows;
//column will be 2
}