How to update ListBoxItem property - c#

I want to update DownloadingSpeed Property which is binded to TextBox in a ListBoxItem. I am generating ListBoxItems in c#. Please guide me how do i update Binding Content of TextBoxes within a ListItemBox in C#.
WPF LisBox Code
<ListBox Width="Auto"
Name="WebsiteList"
MouseUp="SelectedListItem"
SelectedIndex="0"
Grid.Column="1"
Grid.Row="2"
Grid.RowSpan="2"
Margin="0,0,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="920">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Grid Width="920">
<TextBlock FontWeight="Bold" FontSize="18" Width="Auto">
<Hyperlink NavigateUri="http://google.com" FontStyle="Italic">
<Label Content="{Binding WebsiteTitle}" /><Label FontSize="10" Margin="0,0,0,3" Content="{Binding DirectorySize}" />
</Hyperlink>
</TextBlock>
<TextBlock Width="0" TextAlignment="right">
<TextBlock Visibility="Hidden" Text="{Binding DownloadID}"/>
<TextBlock Visibility="Hidden" Text="{Binding DirectoryPath}"/>
<TextBlock Visibility="Hidden" Text="{Binding CurrentTime}"/>
<TextBlock Visibility="Hidden" Text="{Binding CurrentDate}"/>
<TextBlock Visibility="Hidden" Text="{Binding GivenUrl}"/>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Grid Width="920">
<ProgressBar Name="progress1" Maximum="100" Minimum="0" Value="30" Background="#FFF" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=Width}" Height="10" />
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Grid Width="920">
<TextBlock HorizontalAlignment="Left" Width="Auto">Status: <TextBlock Text="{Binding Status}"/></TextBlock>
<TextBlock Width="Auto" TextAlignment="right">
<TextBlock Text="Downloading Speed: "/>
<TextBlock Name="DownloadingSpeed" Text="{Binding DownloadingSpeed}"/>
</TextBlock>
</Grid>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In MainWindow.xaml.cs
private void GenerateList()
{
List<Download> WebsitesList = new List<Download>();
WebsitesList.Add(new Download() {DownloadID = ID, WebsiteTitle = WebTitle, Status = WebStatus, CurrentTime = CurrentTime,CurrentDate = CurrentDate, DownloadingSpeed = DownloadSpeed, DirectoryPath = path, DirectorySize = helper.GetDirectorySize(path),GivenUrl = url });
WebsiteList.ItemsSource = WebsitesList;
}
//get download speed and update DownloadingSpeed
private void updateDownloadingSpeed(object sender, EventArgs e)
{
interfaceStats = NetworkInterface.GetAllNetworkInterfaces()[0].GetIPv4Statistics();
downloadspeed = (interfaceStats.BytesReceived - previousbytesreceived) / 1024;
previousbytesreceived = NetworkInterface.GetAllNetworkInterfaces()[0].GetIPv4Statistics().BytesReceived;
Download.DownloadingSpeed = Math.Round(downloadspeed, 2) + " KB/s"; //Rounding to 2 decimal places and save in DownloadSpeed Property
}
In Download.cs
public class Download : INotifyPropertyChanged
{
private string _DownloadingSpeed = "0 kb/s";
public string DownloadingSpeed
{
get { return _DownloadingSpeed; }
set
{
if (_DownloadingSpeed == value)
return;
_DownloadingSpeed = value;
this.OnPropertyChanged("DownloadingSpeed");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

Add UpdateSourceTrigger for TextBlock.
<TextBlock Name="DownloadingSpeed" Text="{Binding DownloadingSpeed, UpdateSourceTrigger=PropertyChanged}"/>

You might find that your code works if you use WPF properly by defining properties and declaring XAML correctly. It is customary to have an ObservableCollection<T> property that you data bind to the UI collection control. You would then data bind it to the ItemsSource property of the control:
<ListBox ItemsSource="{Binding Items}" ... />
Then, when you want to update any properties of the items, you need to set the properties of the items. This:
Download.DownloadingSpeed = Math.Round(downloadspeed, 2) + " KB/s";
... is not setting the property of an item from the collection. To do that, you'd need to do something like this:
// Use whatever filter you want to find the correct item from the collection
Download downloadInstance = Items.Where(d => d.Name == "SomeName").First();
downloadInstance.DownloadingSpeed = Math.Round(downloadspeed, 2) + " KB/s";

Related

How to delete an object from a ListView using a button in the ListViewItem?

Write a text in the inputTitle TextBox and press the Add button to add item to the TaskList ListView.
public MainWindow()
{
InitializeComponent();
DataContext = new AddItem();
newItems = new ObservableCollection<AddItem> { };
taskList.ItemsSource = newItems;
}
private void addButton_Click(object sender, RoutedEventArgs e)
{
var newItem = new AddItem()
{
Title = inputTitle.Text,
};
newItems.Add(newItem);
taskList.SelectedItem = newItem;
}
private void deleteButton_Click(object sender, RoutedEventArgs e)
{
}
It is to add item to TaskList by pressing the Add button, and I want to delete it by pressing Del button.
<Canvas Margin="0,0,0,10">
<Canvas Height="81" Canvas.Left="10" Canvas.Top="17" Width="380">
<TextBlock x:Name="textBlock" Text="TaskTitle" TextWrapping="Wrap" Height="24" Width="380" FontSize="20" IsEnabled="False"/>
<TextBox x:Name="inputTitle" Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap" Width="320" FontSize="24" Canvas.Top="27" Height="44" TabIndex="1" Canvas.Left="4" Margin="2,2,2,2"/>
<Button x:Name="addButton" Content="Add" Canvas.Left="333" Canvas.Top="32" Height="34" Width="34" Click="addButton_Click" IsEnabled="{Binding CanAdd, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</Canvas>
<ListView x:Name="taskList" Height="500" Width="400" Canvas.Top="116">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox >
<CheckBox.LayoutTransform>
<ScaleTransform ScaleX="2.5" ScaleY="2.5"/>
</CheckBox.LayoutTransform>
</CheckBox>
<TextBlock Text="{Binding Title}" FontSize="30" Width="290"/>
<Button x:Name="deleteButton" Content="Del" Height="34" Width="34" Click="deleteButton_Click"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Canvas>
You can bind the Tag property of Button to the current item.
<ListView x:Name="taskList" Height="500" Width="400" Canvas.Top="116" ItemsSource="{Binding newItems}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox >
<CheckBox.LayoutTransform>
<ScaleTransform ScaleX="2.5" ScaleY="2.5"/>
</CheckBox.LayoutTransform>
</CheckBox>
<TextBlock Text="{Binding Title}" FontSize="30" Width="290"/>
<Button x:Name="deleteButton" Content="Del" Height="34" Width="34" Click="deleteButton_Click" Tag="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
As you bind the Tag property to your current item, you can use that to remove it from the collection.
private void ButtonBase_OnClickDel(object sender, RoutedEventArgs e)
{
var button = (Button)sender;
var item = (AddItem)button.Tag;
newItems.Remove(item);
}

How Can I Access to The Controls in DataTemplate in ListBox in WPF

I have a ListBox including an ItemTemplate with a StackPanel. I want to access that stackpanel and change its visibility.
(Change it's visibility to collapsed when I click mouseleftbutton "closeAll")
I can do that with FindDescendantByName Method but it works for only listbox items on screen (Only first 10 items) but when I am scrolling down, I see that this is not working for other listbox items.
I think that errors occurs because of VisualTreeHelper. What can I use instead of VisualTreeHelper?
Thanks..
XAML CODE
<ListBox x:Name="listBoxEditPast" SelectionMode="Single" Margin="0" Background="#272B34" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderThickness="4,0,0,0" Margin="2,0,0,0" Height="29" Background="#2E323B" Width="1050" BorderBrush="#1373A9" MouseLeftButtonDown="Border_MouseLeftButtonDown">
<DockPanel Name="dockPanelPast" Margin="0,4,0,0">
<Image Name="imgArrow" Source="images/down-arrow.png" HorizontalAlignment="Left" Width="20" Height="18"/>
<TextBlock Text="{Binding CreateDate}" Name="txtTarih" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16"/>
<TextBlock Text="{Binding SarjNo}" Name="txtSarjNo" Foreground="#FF9CA518" HorizontalAlignment="Stretch" VerticalAlignment="Center" FontSize="16" Margin="50,0,0,0" Width="90"/>
<TextBlock Text="{Binding Adi}" Name="txtReceteAdi" Foreground="#FF26A053" VerticalAlignment="Center" FontSize="16" Margin="40,0,0,0" HorizontalAlignment="Stretch"/>
<Button Content="Detaylar" Style="{StaticResource BlueButton}" HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" DockPanel.Dock="Right"/>
</DockPanel>
</Border>
<StackPanel Grid.Row="1" Name="stackPanelDetay" Tag="{Binding ID}">
<DockPanel>
<TextBlock Text="Sipariş No" Foreground="#D9480F" VerticalAlignment="Center" />
<TextBlock Text="Parça" Foreground="#AF0FD9" VerticalAlignment="Center" Margin="50,0,0,0" Width="200" />
<TextBlock Text="Malzeme" Foreground="White" VerticalAlignment="Center" Margin="150,0,0,0" Width="90"/>
<TextBlock Text="Müşteri" Foreground="#AF0FD9" VerticalAlignment="Center" Margin="70,0,0,0" />
</DockPanel>
<DockPanel>
<TextBlock Text="{Binding ID}" Foreground="White" VerticalAlignment="Center" Width="100"/>
<TextBlock Text="{Binding ParcaKoduAdi}" Foreground="White" VerticalAlignment="Center" Margin="5,0,0,0" Width="200" />
<TextBlock Text="{Binding Malzeme}" Foreground="White" VerticalAlignment="Center" Margin="152,0,0,0" Width="90" />
<TextBlock Text="{Binding MusteriKoduAdi}" Foreground="White" VerticalAlignment="Center" Margin="70,0,0,0" />
</DockPanel>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
C# CODE
public static class FrameworkElementExtensions
{
public static FrameworkElement FindDescendantByName(this FrameworkElement element, string name)
{
if (element == null || string.IsNullOrWhiteSpace(name)) { return null; }
if (name.Equals(element.Name, StringComparison.OrdinalIgnoreCase))
{
return element;
}
var childCount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childCount; i++)
{
var result = (VisualTreeHelper.GetChild(element, i) as FrameworkElement).FindDescendantByName(name);
if (result != null) { return result; }
}
return null;
}
}
private void closeAll_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// StackPanel panel = LayoutHelper.FindElement(listBoxEditPast, n => n.GetType() == typeof(StackPanel)) as StackPanel;
for (int i = 0; i < listBoxEditPast.Items.Count; i++)
{
var element = listBoxEditPast.ItemContainerGenerator.ContainerFromIndex(i) as FrameworkElement;
if (element != null)
{
var sp = element.FindDescendantByName("stackPanelDetay") as StackPanel;
if (sp != null)
{
sp.Visibility = Visibility.Collapsed;
}
}
}
}
noting to do with the visualtreehelper, this is because the list is virtualized, so only the first ten items are created and then replaced by the ten next....and you loose your modifications
you must not work with the element in the data template by code
iterate through your data to set a boolean to true/false for all and then change the stack and bind the visibility to this boolean
<StackPanel Grid.Row="1" Name="stackPanelDetay" Visibility="{Binding myBoolean, Converter=BoolToVisibility}">

Gidview item not updating

My page having city listing and searching functionality. When page first time loading, it is showing all record.
When user enter search Text and tap on search button. it is not updating gridview list. I check by placing debug point my code is working fine. but gridview list not showing updated list.
Following is my code.
XAML:
<StackPanel VerticalAlignment="Top">
<TextBlock Style="{StaticResource ListTextBlockStyle}" FontWeight="Bold" Text="{Binding Description}" />
<TextBlock Style="{StaticResource ListTextBlockStyle}" Text="{Binding Description}" />
</StackPanel>
<TextBlock Style="{StaticResource DistanceTextBlockStyle}" TextWrapping="Wrap" Text="XXXm" />
<Image Width="10" VerticalAlignment="Center" Source="ms-appx:///Assets/arrowright.png"/>
</StackPanel>
<Rectangle Height="1" Stroke="Black" StrokeThickness="0.5" Margin="0,3,0,0" />
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<Border Grid.Row="1" Height="60" VerticalAlignment="Bottom">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox x:Name="txtSearch" Margin="0,0,10,0" TextWrapping="Wrap" PlaceholderText="Search" VerticalAlignment="Center" Width="300" Height="50" />
<Image x:Name="imgSearch" Height="50" Width="50" Source="ms-appx:///Assets/btnSearch.png" Tapped="imgSearch_Tapped"/>
</StackPanel>
</StackPanel>
</Border>
C#:
public List<City> gs_CityList = new List<City>();
protected override void OnNavigatedTo(NavigationEventArgs e)
{
fillCityList();
}
private void fillCityList()
{
gs_CityList.Clear();
if (string.IsNullOrEmpty(CityListManagerManager.ms_searchTxt))
{
foreach (City foCity in CityListManagerManager.ms_CityList)
{
City loCity = new City();
loCity.Description = foCity.Description.Replace("\n", "").Substring(0, 15) + "...";
loCity.longtitude = foCity.longtitude;
loCity.latitude = foCity.latitude;
loCity.Location = foCity.Location;
gs_CityList.Add(loCity);
}
}
else
{
foreach (City foCity in CityListManagerManager.ms_CityList.Where(p => p.Description.ToLower().Contains(CityListManagerManager.ms_searchTxt.ToLower())))
{
City loCity = new City();
loCity.Description = foCity.Description.Replace("\n", "").Substring(0, 15) + "...";
loCity.longtitude = foCity.longtitude;
loCity.latitude = foCity.latitude;
loCity.Location = foCity.Location;
gs_CityList.Add(loAEDPin);
}
txtSearch.Text = CityListManagerManager.ms_searchTxt;
}
if (gs_CityList.Count > 0)
{
gvCityList.DataContext = gs_CityList; // --- This binding data to gridview
}
else
MessageBox("City not found...!");
}
private void imgSearch_Tapped(object sender, TappedRoutedEventArgs e)
{
CityListManagerManager.ms_searchTxt = txtSearch.Text.Trim();
fillCityList();
}
You should try changing your List<City> into an ObservableCollection<City>, as this allows the binding to get notified about changes.
You could also think about using a CollectionViewSource as data source for the GridView and modifying its Filter property instead of re-filling the collection.

ListPicker shows object name instead of property's value

XAML:
<toolkit:ListPicker Name="SourceAccountList" Width="680" FontSize="20" Height="50">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding AccountIban}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
Code:
public TransferInternal()
{
InitializeComponent();
Service1Client WCFClient = new ServiceReference1.Service1Client();
WCFClient.GetSourceAccountIntenalListCompleted += new EventHandler<GetSourceAccountIntenalListCompletedEventArgs>(WCFClient_GetSourceAccountIntenalListCompleted);
WCFClient.GetSourceAccountIntenalListAsync(GlobalVariables.ClientID);
}
void WCFClient_GetSourceAccountIntenalListCompleted(object sender, GetSourceAccountIntenalListCompletedEventArgs e)
{
List<AccountModel> AccountList = new List<AccountModel>();
foreach (var ListItem in e.Result)
{
AccountModel Account = new AccountModel();
Account.AccountID = ListItem.AccountID;
Account.AccountIban = ListItem.AccountIban;
AccountList.Add(Account);
}
SourceAccountList.ItemsSource = AccountList;
}
When I try to select something in SourceAccountList it displays object name instead of its properties values. What am doing wrong? I found similar problem
ListPicker shows object name instead of property
But I'm doing the same thing.
You would have to Make the FullModeItemTemplate Like this
<toolkit:ListPicker Name="SourceAccountList" Width="680" FontSize="20" Height="50">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding AccountIban}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding AccountIban}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
List picker has two kinds of itemTemplate the "normal" that displays when you have when you have less than 5 items and the "Full Mode" that displays when you have more than 5.
to create a FullModeItemTemplate you should do something like this
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<TextBlock FontSize="30" Text="{Binding AccountIban}"/>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
The simplest solution is to override the ToString() method in the AccountModel class
public override string ToString()
{
return this.AccountIban;
}

Windows Phone 7 Navigation passing parameter

I have a list box like below.
<ListBox x:Name="CouponListBox" ItemsSource="{Binding Item}" SelectionChanged="CouponListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding MerchantImage}" Height="73" Width="73" VerticalAlignment="Top" Margin="0,10,8,0"/>
<StackPanel Width="130">
<TextBlock Text="{Binding CustomerName}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding MerchantName}" TextWrapping="Wrap" FontSize="20" Foreground="#FFC4C4C4" Padding="10" />
<TextBlock Text="{Binding Distance}" TextWrapping="Wrap" FontSize="16" Foreground="#FFC4C4C4" Padding="10" />
<TextBlock Text="{Binding DistanceInMinutes}" TextWrapping="Wrap" FontSize="16" Foreground="#FFC4C4C4" Padding="10" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And I have a Change Event in .cs file which is
private void CouponListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If selected index is -1 (no selection) do nothing
if (CouponListBox.SelectedIndex == -1)
return;
// Navigate to the new page
System.Diagnostics.Debug.WriteLine("this is a test::" + CouponListBox.SelectedItem.ToString());
NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItem=" + CouponListBox.SelectedIndex, UriKind.Relative));
// Reset selected index to -1 (no selection)
CouponListBox.SelectedIndex = -1;
}
In DetailsPage I could able to print the item Index. But What I want is Customer ID passed in the URL like
"/DetailsPage.xaml?selectedItem=" + CouponListBox.SelectedIndex + "&customerId=" + couponId
Can anyone please tell me where I should include customerId in my XAML file? and that who can I call it in the function.
Thank you,
Karthik
Use this:
if (this.NavigationContext.QueryString.ContainsKey("customerId"))
{
string customerId = this.NavigationContext.QueryString["customerId"];
}
if (this.NavigationContext.QueryString.ContainsKey("selectedItem"))
{
string selectedItem = this.NavigationContext.QueryString["selectedItem"];
}
in the usercontrol's Loaded or other appropriate event.

Categories

Resources