I am trying to learn Wpf.
When the program runs, it gives me the "no listbox source" error.
I am working on a Wpf design but I just started.
The features I have added to the listbox externally, how can I show them as sources. I have no idea about this. I think I have been researching this for 2 hours but I have not found any answer. I have some problems with English. I hope I won't bother you. All details of my codes are below.
Thank you in advance for helping.
//Note : My Class : (public partial class MainWindow : Window)
public void btnListAdd_Click(object sender, RoutedEventArgs e)
{
CronList1.Items.Clear(); // ListBox <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
OpenFileDialog f = new OpenFileDialog();
if (f.ShowDialog().HasValue == true)
{
List<string> lines1 = new List<string>();
using (StreamReader r = new StreamReader(f.OpenFile()))
{
string line;
while ((line = r.ReadLine()) != null)
{
CronList1.Items.Add(line); // ListBox <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}
}
}
2 : I then try to read all in the CronList. I run the method in the class.
CronEvent cronEvent = new CronEvent();
Task.Run(cronEvent.Cron1);
3 :My Code Dont Run!
public async Task Cron1()
{
int sayix = 1;
while (true)
{
try
{
(HttpWebRequest) rq WebRequest.Create(mainWindow.CronList1.Items[sayix].ToString());
rq .Proxy = WebRequest.GetSystemWebProxy();
rq .AllowAutoRedirect = false;
rq .Timeout = 10000;
HttpWebResponse rply= (HttpWebResponse)rq.GetResponse();
StreamReader streamReader = new StreamReader(rply.GetResponseStream());
rply.Close();
streamReader.Close();
mainWindow.CronList1.SelectedIndex = sayix;
sayix++;
if (sayix == mainWindow.CronList1.Items.Count)
{
sayix = 0;
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
await Task.Delay(TimeSpan.FromSeconds(Convert.ToDouble(mainWindow.txtTime.Text)));
}
}
WPF Listbox Code
<ListBox Name="CronList1" Height="390" Margin="2,7,4,0" VerticalAlignment="Top" BorderBrush="Red" Cursor="Arrow" IsSynchronizedWithCurrentItem="False" BorderThickness="1" ClipToBounds="True" SnapsToDevicePixels="True" Grid.Row="1" Grid.RowSpan="2" Grid.Column="1">
<ListBox.ItemBindingGroup>
<BindingGroup/>
</ListBox.ItemBindingGroup>
<ListBox.Effect>
<hc:BrightnessEffect/>
</ListBox.Effect>
</ListBox>
I would recomend using a "data binding" in a ViewModel to make the code more readable.
You create a class (e.g. MainViewModel) and in there you create an ObservableCollection where you add or remove items from.
In the View (xaml file) you then add this ViewModel as a Source and use a Binding to add the items of the collection to your ListView.
Here is an example
Let me know if you can't get it to work.
Related
My item class has string name and bool picked. I use a class with a static ObservableCollection with static methods to maintain the list. This is all working.
I cannot access the checkbox within the listbox item. I've tried multiple ideas I've found on Stack Overflow and elsewhere. I have tried so many things, it would be too long to mention them all.
This is the latest attempt.
It works when I leave the checkbox out of the code.
I understand I'm failing to access the checkbox, it's not being recognized as part of the list item.
But I just don't know how to fix it.
<ListBox x:Name="ListBox1" ItemsSource="{Binding}"
DoubleTapped="ListBox1_DoubleTapped" SelectionMode="Multiple">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="checkBox" Checked="CheckBox_Checked"
IsChecked="{Binding Picked}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
public sealed partial class MainPage : Page
{
Binding myBinding = new Binding();
public MainPage()
{
//....stuff
ListBox1.DataContext = MyList.list;
//... etc
// This works!!
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Update listbox after item has been added and
// user has returned to main page.
ListBox1.UpdateLayout();
}
// This works if I leave the checkbox out of it!!
private void ListBox1_DoubleTapped(object sender, Windows.UI.Xaml.Input.DoubleTappedRoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)this.FindName("checkBox");
// Find the index;
int i = ListBox1.SelectedIndex;
// Some stuff..
// This is what is bound to the checkbox in the xaml!!
item.Picked = true;
try
{
//Manually trying to change the checked of the checkbox!!
// Yes increasingly desperate!!
checkBox.IsChecked = true;
}// Necessary as the checkbox is always throwing this.
catch (NullReferenceException e) { }
}
// Alter Picked value to true on checkbox selection.
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
// Find the index;
//THE INDEX IS ALWAYS 1!!!
int i = ListBox1.SelectedIndex;
try
{
//Trying again to manually manipulate, even though
//the data is supposed to be bound.
item.Picked = true;
}
catch (NullReferenceException ex){}
}
I've tried to only include essential information.
I've left out margins, colors etc and basic declarations.. etc to try and reduce the code.
access a named control inside a XAML DataTemplate
I thought I'd provide an answer to elaborate on the accepted answer with the link that solved this for me.
Basically this link provides a good way to loop through the xaml hierarchy using a visual tree, to find controls within the ListBox. So my xaml looks like this:
<ListBox x:Name="ListBox1" ...>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel ...>
<CheckBox x:Name="checkBox" ... />
<TextBlock ... />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
// To select list item and change Picked value to true.
private void ListBox1_DoubleTapped(object sender, Windows.UI.Xaml.Input.DoubleTappedRoutedEventArgs e)
{
// Find the index;
int i = ListBox1.SelectedIndex;
CheckBox checkBox = getCheckBox(ListBox1);
try
{
// Change Picked bool value.
item.Picked = true;
// Check CheckBox to show item selected.
checkBox.IsChecked = true;
}
catch (NullReferenceException exc) { }
}
// Taken and modified from Jerry Nixon. http://blog.jerrynixon.com/2012/09/how-to-access-named-control-inside-xaml.html
// Find the checkBox for that ListBox item.
CheckBox getCheckBox(ListBox ListBox1)
{
var _ListBoxItem = ListBox1.SelectedItem;
var _Container = ListBox1.ItemContainerGenerator.ContainerFromItem(_ListBoxItem);
var _Children = AllChildren(_Container);
var _Name = "checkBox";
var _Control = (CheckBox)_Children.First(c => c.Name == _Name);
return _Control;
}
// Taken and modified from Jerry Nixon. http://blog.jerrynixon.com/2012/09/how-to-access-named-control-inside-xaml.html
// Get any child controls from ListItem Container.
// Using a visual tree to access elements on the page
// within the xaml heirarchy of nested elements/tags.
public List<Control> AllChildren(DependencyObject parent)
{
var _List = new List<Control> { };
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var _Child = VisualTreeHelper.GetChild(parent, i);
if (_Child is Control)
_List.Add(_Child as Control);
_List.AddRange(AllChildren(_Child));
}
return _List;
}
Basically this can be used for other events and controls. Useful code to have.
I want to search the name in the list box. I am using MVVM pattern in my application.
My Xaml coding for Listbox
<ListBox Height="440" Background="Azure" ItemsSource="{Binding Content,Mode=TwoWay}" HorizontalAlignment="Left" Margin="0,230,0,0" Name="OutGoingInvitationList" VerticalAlignment="Top" Width="468" BorderBrush="#00565353" SelectionChanged="listBox1_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Name="ListPersonImage" Source="{Binding ListImage}" Height="100" Width="100" Stretch="Uniform" Margin="10,2,0,0" ImageFailed="Image_ImageFailed" />
<TextBlock Text="{Binding ListFullName}" Name="ListPersonFullName" Width="200" Foreground="Black" Margin="10,10,0,0" FontWeight="SemiBold" FontSize="22" />
<TextBlock Text="{Binding ListBio}" Name="ListPersonBio" FlowDirection="LeftToRight" Foreground="Black" Margin="-200,50,0,0" FontWeight="ExtraLight" FontSize="20" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here Content have all the list values.
Now it shows the result. Now i want search the person name. I want to write the code in
private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
}
Is it possible to search the names in the listbox. Here i want only show the items in Listbox searched items only. Sorry for the poor English.
Please tell me how to perform this action.
Thanks in advance..
My View Model:
invitationsButton = new ReactiveAsyncCommand();
var invitationResults = invitationsButton.RegisterAsyncObservable(_ =>
{
return HTTPServices.postAndGetResponse((new PersonSearchOperation().GetInvitations(ServiceConstants.Identity_Number)));
});
invitationResults.Subscribe(
x =>
{
ServiceModel sm = new ServiceModel();
Content = new List<ListContactsModel>();
Content1 = new List<ListContactsModel>();
ServiceConstants.Temp_Response = x;
List<ListContactsModel> result = ListContactsModel.extract(x, sm, OutGoingInvitation);
if (!((string.IsNullOrEmpty(sm.NetErrorCode)) && (string.IsNullOrEmpty(sm.ProvResErrCode))))
{
string errCode = !string.IsNullOrEmpty(sm.NetErrorCode) ? sm.NetErrorCode : sm.ProvResErrCode;
string errDesc = !string.IsNullOrEmpty(sm.NetErrorDesc) ? sm.NetErrorDesc : sm.ProvResErrDesc;
MessageBox.Show(errCode + "/" + errDesc);
}
else if (result.Count > 0)
{
Content.AddRange(result);//Outgoing Invitations
}
else
{
MessageBox.Show("There is No Invitations For You"); //Use Resource Bundle
}
}
);
Now Content have all the result.
Please tell me now where i have to implement Search operation?
Actually i have no idea where i have to write the Search Operation Code??
In My view Model I have add this code. I can see the output in Console Window. But UI is not updating.
public void SearchMethod(String searchValue)
{
Console.WriteLine("searchValue...." + searchValue);
Console.WriteLine("ServiceConstants.Temp_Response ...." + ServiceConstants.Temp_Response);
AppGlobalConstants.Temp_SearchValue = searchValue;
ServiceModel sm = new ServiceModel();
Content = new List<ListContactsModel>();
List<ListContactsModel> result = ListContactsModel.extract(ServiceConstants.Temp_Response, sm, OutGoingInvitation);
if (!((string.IsNullOrEmpty(sm.NetErrorCode)) && (string.IsNullOrEmpty(sm.ProvResErrCode))))
{
string errCode = !string.IsNullOrEmpty(sm.NetErrorCode) ? sm.NetErrorCode : sm.ProvResErrCode;
string errDesc = !string.IsNullOrEmpty(sm.NetErrorDesc) ? sm.NetErrorDesc : sm.ProvResErrDesc;
MessageBox.Show(errCode + "/" + errDesc);
}
else if (result.Count > 0)
{
Content.AddRange(result);
Console.WriteLine("Content.Count==>>" + Content.Count);
}
}
In My CS file
private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
listContactsViewModel.SearchMethod(userIDTextBox.Text);
}
Sorry. I am very new to windows phone application development. In fact this is my very first project. That's why i don't have any idea. Please tell me where i have to make changes??
In your ViewModel you should have a private collection to hold the orignal list while you can set the search result in content.
In your viewmodel
private List<YourClass> orignalList;
public void Search(string query)
{
// do your query
List<YourClass> list = get...;
// clear content
Content.Clear();
foreach(var item in list)
{
Content.Add(item)
}
}
If you clear the query, you use the orignalList to fill Content.
Remember to set Content as ObservableCollection
I am developing a Windows Phone 8 application and have some pictures already in it which are populated into a listbox like this
<ListBox x:Name="Control" ItemsSource="{Binding Pictures}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="WhiteSmoke" Margin="10">
<Image Source="{Binding Source}" Margin="10"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The ViewModel is simple at the momment
public class MainPageViewModel : NotificationObject
{
private ObservableCollection<Picture> _pictures;
public MainPageViewModel()
{
Pictures = new ObservableCollection<Picture>
{
new Picture
{
Source = new BitmapImage(new Uri("../Images/Pictures/1.jpg", UriKind.Relative))
}
//Add more images here
};
}
public ObservableCollection<Picture> Pictures
{
get { return _pictures; }
set
{
_pictures = value;
RaisePropertyChanged(() => Pictures);
}
}
}
I now want that by tapping on an image the user gets options for sharing
void ShowShareMediaTask(object sender, GestureEventArgs e)
{
ShareMediaTask shareMediaTask = new ShareMediaTask();
shareMediaTask.FilePath = //something needs to go here
shareMediaTask.Show();
}
Any ideas how I can get the physical (full) path of this image?
It looks like you are referencing images stored in the application folder (in the project) so the ShareMediaTask can't access it.
The ShareMediaTask requires the photo to be in the Media Library.
What you need to do is save the photo the the Media Library and then call the ShareMediaTask with the path of the saved image (don't forget to add the using Microsoft.Xna.Framework.Media.PhoneExtensions; to have access to the GetPath() extension method).
var picture = mediaLibrary.SavePicture(fileName, stream);
shareMediaTask = new ShareMediaTask();
shareMediaTask.FilePath = picture.GetPath(); // requires using Microsoft.Xna.Framework.Media.PhoneExtensions;
shareMediaTask.Show();
yes... you can generate tap event of list box follow below code
private void Control_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
ObservableCollection<Picture> pictureobj=new ObservableCollection<Picture>();
ListBox lst = (ListBox)sender;
int i = lst.SelectedIndex;
if (lst.SelectedValue == null)
{
}
else
{
Pictures obj = (Pictures)lst.SelectedValue;
ShareMediaTask shareMediaTask = new ShareMediaTask();
shareMediaTask.FilePath = obj.yoursetterimagepath
shareMediaTask.Show();
}
}
hope it will help you
MainPage.xaml
<TextBlock Text="{Binding Pathname, Source={StaticResource ViewModel}, Mode=OneWay}" />
App.xaml
<ResourceDictionary>
<vm:InspectViewModel x:Key="ViewModel" />
</ResourceDictionary>
ViewModel
private string _pathname = null;
public string Pathname
{
get { return _pathname; }
set
{
if (_pathname != value)
{
_pathname = value;
RaisePropertyChanged("Pathname");
}
}
}
public void UpdatePathname(string path)
{
Pathname = path;
}
MainPage CodeBehind
private void lazyNavTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
InspectViewModel vm = new InspectViewModel();
var path = view.GetPath().ToArray();
string pathname = null;
// to figure out what the pathname is
for (int i = 0; i < path.Count(); i++)
{
TreeList treeItem = (TreeList)path[i].Key;
if (i == path.Count()-1)
pathname = pathname + treeItem.Name;
else
pathname = pathname + treeItem.Name + " : ";
}
vm.UpdatePathname(pathname);
}
The bound TextBlock shows nothing, nada, zip. The pathname shource is changing correctly but nothing seems to happen when I fire the INotifyPropertyChanged event on change.
I am sure I'm missing something really obvious but I can't figure out what!
You are creating 2 instances of your ViewModel:
in App.xaml (in app resources, this is the instance which is bound to)
in MainPage code-behind (InspectViewModel vm = new InspectViewModel(), this is the modified instance)
You should use single instance of you ViewModel, for example,
var vm = (InspectViewModel)Application.Current.Resources["ViewModel"];
instead of creating it in MainPage code-behind.
It's because you create an instance from your viewmodel every times in the lazyNavTree_SelectedItemChanged. You should use only one.
Looks like you just missed the Path in your binding, try;
Text="{Binding Path=Pathname, Source={StaticResource ViewModel}, Mode=OneWay}"
EDIT: Apparently this was not the problem, but keeping this answer since xhedgepigx provided a useful link as a comment below.
I'm a noob when it comes to WPF; In win forms I can do this:
public void blah()
{
using( var o = new OpenFileDialog())
{
if(o.ShowDialog() == DialogResult.OK)
{
PictureBox p = new PictureBox();
p.ImageLocation = o.FileName;
p.AutoSize = SizeMode.AutoSize;
this.Controls.Add(p);
}
}
}
But in WPF I have no idea at all and not even MSDN will give me any clear info on how to insert a pic onto the form at runtime! Can someone please help?
Thank you very much
Basically you need to create a System.Windows.Controls.Image and set its Source to a System.Windows.Media.Imaging.BitmapImage. Then add the image to the Children of the Container. You may want to put the image inside of another container first like a Canvas. Here's a quick translation of your code, but you'll likely need to play with it a bit to get it just right.
public void blah()
{
using( var o = new OpenFileDialog())
{
if(o.ShowDialog() == DialogResult.OK)
{
Image i = new Image();
i.Source = new BitmapImage(o.FileName);
//p.AutoSize = SizeMode.AutoSize; <= not sure about this part.
this.Children.Add(i);
}
}
}
You could use XAML and some bindings (and possibly a converter to convert a string to an image source). It's more in keeping with the WPF way of doing things.
Example without converter:
XAML
<Window
...
x:Name="this"
DataContext="{Binding ElementName=this}">
<Grid>
<ListView ItemsSource="{Binding MyImageCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>
Code Behind
public class Window1 : Window {
public ObservableCollection<ImageSource> MyImageCollection { get; set; }
...
public void blah()
{
using( var o = new OpenFileDialog())
{
if(o.ShowDialog() == DialogResult.OK)
{
MyImageCollection.Add(new BitmapImage(new Uri(o.FileName)));
}
}
}
}
Here is an easier way to do it.
Image.Source = new BitmapImage(new Uri("C:\MyImage.jpg");