I have a datatemplate for a listbox stored in the ResourceDictionary. The template contains a button which when clicked should pass the listbox item to a seperate listbox
<DataTemplate x:Key="ListBoxContentPresenterTemplate">
<StackPanel Orientation="Horizontal">
<StackPanel Height="75" Width="100">
<TextBlock x:Name="Surname" Text="{Binding Property1}" FontFamily="Arial" FontSize="16" FontWeight="Bold" d:LayoutOverrides="Width"/>
<TextBlock x:Name="Firstname" Text="{Binding Property2}" Foreground="#FFC9C23E" FontFamily="Arial" FontSize="12" d:LayoutOverrides="Width"/>
</StackPanel>
<Button x:Name="Button1" Content="Press" />
</StackPanel>
</DataTemplate>
I don't know how to fire the event as adding it in the xaml as I normally would doesn't work here(presumably as it's a template).
Any help would be much appreicated.
DataTemplate is not the problem to subscribe to events. May be only if your DataTemplate is located in a separate resources file, so you have no rational place to place the event handler. If so you can make use of Commands (I believe this will work in version 3 too).
Related
I have a listbox which binds to an observable collection of a custom type which displays each item through my data template:
<ListBox x:Name="ListBox" Style="{StaticResource CustomListBox}" ItemsSource="{Binding HandStats}" Height="410" Width="150" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding HoleCards[0].CardParts.Value}" Margin="2"/>
<Image Source="{Binding HoleCards[0].SuitImagePath}" Width="10" Height="10" Margin="2"/>
<TextBlock Text="{Binding HoleCards[1].CardParts.Value}" Margin="2"/>
<Image Source="{Binding HoleCards[1].SuitImagePath}" Width="10" Height="10" Margin="2"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Runs:" Margin="2"/>
<TextBlock Text="{Binding NumberOfRuns}" Margin="2"/>
<TextBlock Text="Players:" Margin="2"/>
<TextBlock Text="{Binding NumberOfPlayers}" Margin="2"/>
</StackPanel>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding Path=DataContext.PopulateReport, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding ElementName=ListBox, Path=SelectedItem}"/>
</StackPanel.InputBindings>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Image of my listbox:
http://imgur.com/a/QGz8z
Now ideally when I click anywhere in the stack panel for each item, the item will be selected and the command will be fired. But my problem is that the item selection and the command firing is not working as it should.
The item will only become selected if I click in between the text blocks or in the empty space to the right of the text blocks, but the command will not be fired. The command will only fire once I have firstly selected the item, and then click again onto one of the text blocks or one of the images.
I'm still quite new to WPF so if I'm not making much sense please let me know, thanks in advance :)
So instead of using input bindings I decided to use a different method. I created a property in my vm and bound this to the selected item of my list. So now every time I select a new item (which works perfectly now) the property is updated in my vm. Simple!
Try to set the Background property of the StackPanel to Transparent:
<StackPanel Orientation="Vertical" Background="Transparent">
...
If it doesn't have a Background the click events won't be raised as expected.
I have a TextBox in my application that i am developing and the binding is done in the xaml
I want to be able to raise an event when the binding of the TextBox Text Property is completed meaning when the text is loaded/changed through binding into the TextBox how do i achive this?
I tried TextChanged Event also Loaded Event but no luck right after the Binding is complected so how do i do it?
<ListBox x:Name="listBoxCategories" Background="Transparent" BorderThickness="0" Grid.Row="4" Grid.ColumnSpan="2" Margin="0" Padding="0" ItemContainerStyle="{StaticResource ListBoxItemStyle}" ItemsSource="{Binding ElementName=discussion_categoryDomainDataSource, Path=Data}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stackPanelCategory" Orientation="Vertical" Margin="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBlock x:Name="TextBlockCategoryId" Text="{Binding Path=CategoryID}" />
<toolkit:Expander IsExpanded="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Style="{StaticResource ForumExpanderStyleRight}">
<toolkit:Expander.Header>
<TextBlock FontSize="16" FontWeight="Bold" Foreground="White" Margin="4,0,4,0" Text="{Binding CategoryName}" LayoutUpdated="TextBlock_LayoutUpdated" />
</toolkit:Expander.Header>
<ListBox x:Name="listBoxBoards" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent" BorderThickness="0" Margin="0" Padding="0" ItemContainerStyle="{StaticResource ListBoxItemStyle}" ItemsSource="{Binding CategoryBoards}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0" HorizontalAlignment="Stretch" x:Name="GridBoard">
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</toolkit:Expander>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
at this line
<TextBlock x:Name="TextBlockCategoryId" Text="{Binding Path=CategoryID}" />
I want an event where when the Binding is completed i want to give a different data source for the list box under the parent stack panel so i need the binding event so when i have the catedory id int he text block which later will be hidden in the xaml ( which now is not collapsed for testing reasons )
This is a slightly peculiar thing to want to do, it might help if you tell us why you are wanting to do this?
However, with no other information to hand, I will propose a solution.
If the TextBox API events do not provide the infomation you need, try handing the LayoutUpdated event. This event fires each time layout occurs, which is typically as elements ae added to the visual tree. WHen this event fires inspect your TextBox.Text property to see if it is set.
This solved the problem for me :)
<TextBlock FontSize="16" FontWeight="Bold" Foreground="White" Margin="4,0,4,0" Text="{Binding CategoryName}" Loaded="TextBlock_Loaded" />
Loaded event in the inner Text block rather than the upper textblock because by the time this is loaded the upper text block's text is already bound so i can retrive the ID :)
I have a ListView bound to an ObservableCollection of CustomerContacts.
It works great so far, but being new to this, I'm not sure how to do the next part.
Each customer contact has several contact types, which I want to display under their name.
So inside of CustomerContacts I have another ObservableCollection of ContactTypes.
Here is my current datatemplate:
<DataTemplate x:Key="iconTemplate">
<DockPanel Height="133" Width="150">
<Image Source="/Tracks%203.5;component/Images/NoPic.png" Height="25" Width="25" Margin="1,0" />
<TextBlock DockPanel.Dock="Top" Text="{Binding FullName}" Margin="5,3,5,0" FontWeight="Bold" HorizontalAlignment="Left" />
<<TextBlock Text="{Binding Title}" Margin="5,0,5,3" HorizontalAlignment="Left" />>
</DockPanel>
</DataTemplate>
And here's my first attempt at putting the listview inside:
<DataTemplate x:Key="iconTemplate">
<DockPanel Height="133" Width="150">
<Image Source="/Tracks%203.5;component/Images/NoPic.png" Height="25" Width="25" Margin="1,0" />
<TextBlock DockPanel.Dock="Top" Text="{Binding FullName}" Margin="5,3,5,0" FontWeight="Bold" HorizontalAlignment="Left" />
<ListView ItemsSource="{Binding ContactTypes}">
<ListView.Template>
<ControlTemplate TargetType="ItemsControl">
<ItemsPresenter/>
</ControlTemplate>
</ListView.Template>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Margin="3,0,0,0" HorizontalAlignment="Center" Text="{Binding Path=ContactType}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--<TextBlock Text="{Binding Title}" Margin="5,0,5,3" HorizontalAlignment="Left" />-->
</DockPanel>
</DataTemplate>
I want to replace the TextBlock bound to Title with a ListView/ListBox/ItemsControl bound to the items in ContactTypes.
Somewhat similar to this question: < WPF: bind to a List inside a class > but without all the codebehind. It would be nice to have it in the XAML.
There's a couple things I would do here:
Simplify what you're trying to do in order to isolate the problem. Instead of that whole ListView business, just put in there an ItemsControl: <ItemsControl ItemsSource="{Binding ContactTypes}" /> That'll give you the default view of things, which may just show you the data type of your objects (whatever ContactTypes is), but it'll let you know if the binding is working. If it is, you'll get something listed there. If it isn't, you won't.
If you're not getting anything listed, go use Snoop to drill into it and look for errors. Snoop shows the databinding errors, allows you to inspect the DataContext of each of the items, etc.
If you're still having problems, it might benefit us if you posted your class definitions and your code where you wire things up. There might be some other underlying issues (for instance, is the ContactTypes property null when the binding initially occurs and you're not using INPC to let the binding system know when it changes?).
I have a two pages say Main.xaml and Details.xaml.Each page has a ListBox and I am setting each of it to a collection in ViewModel(Same collection).The strange thing is that when i select an item in Details page it calls the SelectionChanged event handler on Main page and Details page.Is this a bug?
I have solved the problem by unhooking SelectionChanged eventhandler in OnNavigatedFrom() method.
EDIT
In Main.Xaml I have something like below:
<ListBox Name="MainDataListBox" Margin="8,113,8,8" ItemsSource="{Binding DataList}" SelectionChanged="MainDataListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Border BorderThickness="3" BorderBrush="#A5FFFFFF" Width="80" Margin="0,20,0,20" Height="60">
<Image Source="{Binding ImageUrl, Mode=OneWay}" VerticalAlignment="Stretch" Margin="0,0,0,0" Width="80" Height="60" Stretch="Fill" />
</Border>
<TextBlock TextWrapping="Wrap" Text="{Binding Title}" FontSize="40" FontWeight="Normal" VerticalAlignment="Center" Margin="30,0,0,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In Details.xaml also I have same kind of ListBox:
<ListBox Name="DetailDataListBox" Margin="8,113,8,8" ItemsSource="{Binding DataList}" SelectionChanged="DetailDataListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Border BorderThickness="3" BorderBrush="#A5FFFFFF" Width="80" Margin="0,20,0,20" Height="60">
<Image Source="{Binding ImageUrl, Mode=OneWay}" VerticalAlignment="Stretch" Margin="0,0,0,0" Width="80" Height="60" Stretch="Fill" />
</Border>
<TextBlock TextWrapping="Wrap" Text="{Binding Title}" FontSize="40" FontWeight="Normal" VerticalAlignment="Center" Margin="30,0,0,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Both of the Pages Main and Details have seperate EvenHandlers MainDataListBox_SelectionChanged and DetailDataListBox_SelectionChanged.
The problem is when i select an Item in Details Page MainDataListBox_SelectionChanged is called first and then DetailDataListBox_SelectionChanged.
Also my viewmodel is a static one in App.cs and I am setting the data context of both these pages to same viewmodel.
Thanks and Regards
vaysage
As both listsboxes were bound to the same dataset a change in the selected time in one list would have affected the other.
Obviosuly you're found a work around but I'd recommend having a unique view model for each page. If the page is just a different way of displaying the same data use a single page and alter the display as appropriate. (Creating your own visual states may be a good way to do this.)
I'm trying to create a user control that is a combobox that, when opened, presents a treeview of heirarchal data.
I created the user control and replaced a portion of the template in Popup with:
<ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1">
<sdk:TreeView x:Name="Tree">
</sdk:TreeView>
</ScrollViewer>
However, I'm not sure how to enable binding on this. The treeview needs to be bound to a different datacontext than the combobox. I tried implementing a DependencyProperty on the user control that would allow me to set the datacontext, but I'm definitely not going about it the right way. At this point, all I get is an empty treeview.
Any help on this would be greatly appreciated.
P.S. One additional caveat is that I need to template the treeview like so:
<sdk:TreeView x:Name="Tree">
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding ChildUnits}">
<StackPanel Orientation="Vertical" Width="200">
<TextBlock x:Name="name" TextWrapping="Wrap" Text="{Binding Name}" FontWeight="Bold" />
<TextBlock x:Name="type" Text="{Binding Id}" FontStyle="Italic" FontSize="10" Foreground="Gray" />
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
</sdk:TreeView>