I'm working on my first WP7 App and this problem causes me some headache.
I've a ListBox defined like this
<ListBox Grid.Row="1" ItemsSource="{Binding MyItemList}" SelectedItem="{Binding MySelectedItem}">
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="35" />
<TextBlock Text="{Binding Details}" FontSize="15"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Binding the ItemsSource works fine, but the MySelectedItem-Property doesn't get updated when selecting an item. Is this function not implemented (like in WPF) or am I just doing something? :-)
Just use -
SelectedItem="{Binding MySelectedItem, Mode=TwoWay}" and it should be fine.
You might have to set IsSynchronizedWithCurrentItem="True" for your ListBox.
This is my workaround.. I hope someone will post a more elegant solution.
XAML:
<ListBox Name="DecksListBox" ItemsSource="{Binding MyItemsList}"
SelectionChanged="UpdateSelectedItem"
Code-behind:
private void UpdateSelectedItem(object sender, SelectionChangedEventArgs e)
{
// Ignore if there is no selection
if (DecksListBox.SelectedIndex == -1)
return;
App.ViewModel.MySelectedItem = App.ViewModel.MyItemsList[DecksListBox.SelectedIndex];
}
Maybe this might help someone in the meantime.
Related
WPF beginner here.
I managed to bind a TreeView control to a DataViewManager using the code shown at the end of this post. Everything works fine when populating the TreeView control initially but I want to implement two way binding so that I can use a textbox to filter out unwanted TreeView items.
My problem is that the treeview isn't updated if
I'm trying to use something like this:
private void SearchTree_TextChanged(object sender, TextChangedEventArgs e)
{
if(SearchTree.Text.Length>0)
Command.dvm.DataViewSettings["Categories"].RowFilter = "CategoryName LIKE '%"+SearchTree.Text+"%'";
}
Can anyone please help me find out what I'm doing wrong here?!
Xaml:
...
<UserControl.Resources>
<ObjectDataProvider
x:Key="dataVMProvider"
MethodName="CreateDataVM"
ObjectType="{x:Type local:DataVMCreator}"
/>
<DataTemplate x:Key="InstancesTemplate">
<TextBlock Text="{Binding InstanceUID}"/>
</DataTemplate>
<HierarchicalDataTemplate
x:Key="SymbolsTemplate"
ItemsSource="{Binding Symbols2Instances}"
ItemTemplate="{StaticResource InstancesTemplate}"
>
<TextBlock Text="{Binding SymbolName}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate
x:Key="FamiliesTemplate"
ItemsSource="{Binding Families2Symbols}"
ItemTemplate="{StaticResource SymbolsTemplate}"
>
<TextBlock Text="{Binding FamilyName}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate
x:Key="CategoriesTemplate"
ItemsSource="{Binding Categories2Families}"
ItemTemplate="{StaticResource FamiliesTemplate}"
>
<TextBlock Text="{Binding CategoryName}"/>
</HierarchicalDataTemplate>
</UserControl.Resources>
...
<TreeView
x:Name="ElementsTree"
...
DataContext="{StaticResource dataVMProvider}"
ItemsSource="{Binding Categories}"
ItemTemplate="{StaticResource CategoriesTemplate}"
/>
The DataViewManager comes from:
public static class DataVMCreator
{
public static DataViewManager CreateDataVM()
{
return Command.dvm;
}
}
Try this binding for the DataContext of your TreeView:
DataContext="{Binding Source={StaticResource dataVMProvider}}"
<TabItem Name="tbInActive" Header="Previous" Width="100" Height="100">
<ListBox Name="lbActive"
DockPanel.Dock="Top"
ItemContainerStyle="{DynamicResource SelectedItemContainer}">
<ListBox.ItemTemplate>
<DataTemplate >
<EventDet:EventSumDetail x:Name="ItemCtrl"
SelectedItem="{Binding ElementName=lbInActive, Path=SelectedItem}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- ... -->
</TabItem>
In my codebehind I tried
this.lbActive.SelectedItem = null; and this.lbActive.UnselectAll(); and (edit) this.lbActive.SelectedIndex = -1;
But they had no effect.
There is no reason why this.lbActive.SelectedItem = null; should not work. (It works on a clean slate ListBox)
I'm quite sure the problem lies with your custom parts, either SelectedItem="{Binding ElementName=lbInActive, Path=SelectedItem}" is forcing a selection, or a binding in your ItemContainerStyle does so.
I guest that EventDet:EventSumDetail is a kind of ListBoxItem or something like that.
The problem you had a OneWay binding(by default)... you had to explicitly make it TwoWay binding.. like this:
<EventDet:EventSumDetail SelectedItem="{Binding ElementName=lbInActive, Path=SelectedItem, Mode=TwoWay}" />
Also, you don't need to name (x:Name="ItemCtrl"), in this case it's unnecessary.
I will show you the exact code and output of the code...
This is my linq .dbml file
This i the combobox cbx_contact code :
<ComboBox Height="22.669" Margin="107.769,43.75,424.266,0" Name="cbx_contact" VerticalAlignment="Top" IsTabStop="True" SelectedValuePath="ContactID" IsSynchronizedWithCurrentItem="True" IsEditable="True" IsTextSearchEnabled="True">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=ContactName}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This is the .cs file :
public Contacts()
{
InitializeComponent();
DataClasses1DataContext db = new DataClasses1DataContext();
cbx_contact.ItemsSource = db.Contacts;
cbx_contact.SelectedIndex = 0;
}
This is the output view of the combobox :
Here in the drop down list of combobox i get all the values but when i select any value the text does not change it gives Contact_Manager.Contact....
I dont know what i am missing here...
I have binded combobox like this before also it was working at that time but here it is creating probs...
thanks in advance for the help...
Applying the concepts from this answer:
<ComboBox Height="22.669" Margin="107.769,43.75,424.266,0" Name="cbx_contact" VerticalAlignment="Top" IsTabStop="True" SelectedValuePath="ContactID" IsSynchronizedWithCurrentItem="True" IsEditable="True" IsTextSearchEnabled="True"
TextSearch.TextPath=ContactName
>
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=ContactName}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I'm developing a Windows Phome application. I have the following ListBox on a page:
<ListBox Margin="10,10,8,8" x:Name="WallList">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="ListBoxItemLayout" Background="Transparent" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.33*"/>
<ColumnDefinition Width="0.77*"/>
</Grid.ColumnDefinitions>
<Image HorizontalAlignment="Left" Margin="0" Source="{Binding ImagePath}" Height="200"/>
<StackPanel Margin="5,0,0,0" Grid.Column="1">
<TextBlock x:Name="Name" TextWrapping="Wrap" Text="{Binding Name}" Style="{StaticResource PhoneTextTitle2Style}"/>
<TextBlock x:Name="Comment" Margin="0,5,0,0" TextWrapping="Wrap" Text="{Binding Comment}" Style="{StaticResource PhoneTextNormalStyle}" Height="130"/>
<TextBlock x:Name="When" TextWrapping="Wrap" Text="{Binding When}" Style="{StaticResource PhoneTextTitle3Style}" VerticalAlignment="Bottom"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm using this to fill the ListBox on Loaded event:
this.WallList.ItemsSource = StartingWall.GetWallPosts();
And now I want to add more items programmatically when the user write down some text on a TextBox and click on a button. I want to place this text on Comment field.
I'm gooing to fill the rest fields with default data.
My question is:
How can I add more items to WallList ListBox?
Someone has suggested to do the following:
public ObservableCollection<WallPostEntry> MyWallPosts {get;set;}
// Initialize MyWallPosts to whatever
MyWallPosts.Add(new WallPostEntry("new entry"));
<ListBox Margin="10,10,8,8" x:Name="WallList" ItemsSource="{Binding MyWallPosts}">
But Binding ListBox ItemsSource doesn't work for me. I'm initializing MyWallPosts on constructor, just before InitializeComponent();, like this:
public Wall()
{
MyWallPosts = StartingWall.GetWallPosts();
InitializeComponent();
}
Any advice?
Thanks.
I see a couple wierd things:
first, you're using the itemssource binding in one place, but explicitly setting it in another? setting something in code will override/undo any bindings, so that could cause a problem (but it looks like you're setting it to the same thing so that shouldn't make a difference, but i'd remove the this.WallList.ItemsSource = StartingWall.GetWallPosts(); call entirely, and leave the ItemsSource="{Binding MyWallPosts}" in the xaml. the point of using bindings is to get rid of this kind of code)
second, you're setting mywallposts and using a binding, but not setting the datacontext on your object itself? simplest in your example would be to just add one line to your constructor:
public Wall()
{
DataContext = this;
MyWallPosts = StartingWall.GetWallPosts();
InitializeComponent();
}
My next suggestion would be to simplify until it works. leave the listbox but comment out all of the item/data templating to make sure that you don't have a bug in your template
Could he just add
a DataContext property to this:
<ListBox Margin="10,10,8,8" x:Name="WallList" ItemsSource="{Binding MyWallPosts}">
so:
<ListBox Margin="10,10,8,8" x:Name="WallList" ItemsSource="{Binding MyWallPosts}" DataContext="{Binding MyWallPosts}">
Would there be any way of setting the dataContext declarativelly?
tks,
Oscar
I want to drag data from a ListView and drop it in a TreeView(the draging works fine). I use DataBinding and ItemTemplate to fill the TreeView.
<TreeView ItemsSource="{Binding Groups}" Name="tvGroups" AllowDrop="True"
Drop="tvDrop" DragOver="tvDragOver">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Participants}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<Button Tag="{Binding .}" Click="Button_Click_2">
<Image Source="Resources/cross.png" />
</Button>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Alias}" />
<Button Tag="{Binding .}" Name="btnDeleteParticipants" Click="btnParticipants_Click" >
<Image Source="Resources/cross.png" />
</Button>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
private void tvDrop(object sender, DragEventArgs e)
{
if (e.Effects == DragDropEffects.Copy &&
e.Data.GetDataPresent(typeof(Participant)))
{
Participant data = e.Data.GetData(typeof(Participant)) as Participant;
}
}
A Participant is dragged from the ListView to the TreeView. Now I need to find the Group. Any ideas where to get the right Group from the TreeView?
I would simply set the Drop="tvDrop" and DragOver="tvDragOver" on the StackPanel in the HierarchicalDataTemplate's ItemTemplate.
This way
1) You don't have any risk of getting an event when something is dropped out of a group
2) You can safely cast the Sender to a FrameworkElement and get the DataContext and cast it to your class.
You can also set a different handler on the treeview itself if you need to support dragging out of the groups.