I have situation
<Grid>
<FlipView x:Name="flip1">
...
</FlipView>
<FlipView x:Name="flip2">
...
</FlipView>
</Grid>
How I can synchronize manipulations on these two FlipView controls?
If user makes 'swipe' gest on grid, booth of FlipViews should change page.
You could try binding SelectedItem property of these two - e.g. set SelectedItem={Binding SelectedItem, ElementName=flip2, Mode=TwoWay} on flip1. The results with touch manipulation feedback might not be ideal though and you can't make it perfect even if you try to manually synchronize the offset on the ScrollViewer in the template of each of the FlipViews.
Related
Okay, to start, I'm pretty inexperienced with WPF and XAML, so any pointers or advice would be greatly appreciated.
I have a scheduling program that I'm working on that I need some help setting up. I had things working previously, but it wasn't organized correctly. I had UI elements in my ViewModels that I would add to a StackPanel at the initialization of the MainWindow. Generally not MVVM style coding. So I made some views (UserControls) to display the things I have, and most everything broke.
Basically, I have a Schedule ViewModel that has some parameters and a list of a different Room ViewModels. Each Room ViewModel has a RoomSchedule ViewModel that contains a list of RoomEvent ViewModels.
I'm trying to write controls for the things that need displaying. I've created a Schedule view, which has a list box of Room views, and the Room view uses the RoomEvent view to display the events of the room. The Room view uses the WPF Extended Toolkit's TimelinePanel, the rest of the controls are pretty much basic controls. The general idea has been: a model provides data to the ViewModel, which massages that data to what needs to be displayed. So an Event should know how to display itself, a Room should know how to display itself, and the Schedule should know how to display itself.
The problem I'm running into is: now that I've scooted everything from the xaml.cs or ViewModel files to their appropriate places, the controls aren't rendering at all. I've been reading other SO postings where people have the same problem, but none of them seem to work for beginner stuff like this. I think I'm close, it seems like all the controls are being created, and the DataContext's are being set correctly, but nothing is showing up.
This is, basically, what I have so far. I left some of the xaml boilerplate stuff off for succinctness:
Schedule.xaml:
<StackPanel>
<ListBox ItemsSource="{Binding Rooms}" >
<ListBox.ItemTemplate>
<DataTemplate>
<localcontrols:RoomView ScheduleStart="{Binding ElementName=ScheduleControl, Path=DataContext.Start}"
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
</StackPanel>
RoomView.xaml:
<extended:TimelinePanel BeginDate="{Binding localcontrols:ScheduleStart}" EndDate="{Binding localcontrols:ScheduleEnd}"
<ItemsControl ItemsSource="{Binding Path=mRoomSchedule.mScheduledEvents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<localcontrols:EventView />
</DataTemplate>
</ItemsControls.ItemTemplate>
</ItemsControl>
</extended:TimelinePanel>
EventView.xaml:
<Border BorderThickness="1" BorderBrush="Black" extended:TimelinePanel.Date="{Binding mStartTime}" extended:TimelinePanel.DateEnd="{Binding mEndTime}">
<TextBlock Background="{Binding mColor}" Text="{Binding mEventID}" />
</Border>
The ScheduleStart and ScheduleEnd are dependency properties defined in RoomView.xaml.cs. My thinking was that Schedule would have Start and End properties that would be set in its constructor, and the RoomViews in the ListBox would bind to those properties to set the TimelinePanel's BeginDate and EndDate.
Maybe your bindings are wrong. When I need to bind to a dependency property I use the ElementName feature of binding to say which control I want and I give the root node a name, in this case Root. It's one way to solve it.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Weingartner.Controls"
x:Class="RoomView"
x:Name="Root">
<extended:TimelinePanel
BeginDate="{Binding ElementName=Root, Path=ScheduleStart}"
EndDate="{Binding ElementName=Root, Path=ScheduleEnd}"
>
<ItemsControl ItemsSource="{Binding Path=mRoomSchedule.mScheduledEvents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<localcontrols:EventView />
</DataTemplate>
</ItemsControls.ItemTemplate>
</ItemsControl>
</extended:TimelinePanel>
</UserControl>
In our application we have a screen design feature which is comprised of a custom ScreenDesignPanel and a Property Grid with a ComboBox at the top which points to the selected item on the ScreenDesignPanel. This allows the user to select the UIElement via the ComboBox or via the mouse to set its properties. We achieve this by binding the ItemsSource of the ComboBox to the ScreenDesignPanel's Children collection, then binding their SelectedItems together. This works great.
However, for whatever reason, if the SelectedItem is a ContentControl or a subclass like Button the ItemTemplate specified for the ComboBox is ignored for the 'selected item area' but it is applied when displaying the item in the dropdown list. If the SelectedItem is not a ContentControl, the template is used in both cases.
This also is seemingly specific to the ComboBox. If we use any other selector control: ListBox, ListView, ItemsControl... even third-party ComboBox controls... they all work as expected, properly applying the DataTemplate. ComboBox is doing something internally which no other control is doing.
Note: Below is an over-simplified example for illustrative purposes of the issue only. It is not how we're actually using it as described above.
Also of note: In the DataTemplate for the ComboBox.ItemTemplate, we are only using properties (i.e. Foreground in the example), and are not displaying the DataContext (i.e. the actual ContentControl) itself. This is important because again, the actual control already exists on the ScreenDesignPanel and therefore can't be used for display in the ComboBox's ItemTemplate as it would have two parents which isn't allowed. In other words, it is being used purely as data here.
One last thing... we have a working solution in our app, which was to wrap the Children before binding it to the ComboBox.ItemsSource. However, I'm still curious as to why the ComboBox behaves the way it does which is SPECIFICALLY what I'm asking. (In other words, I'm not looking for other solutions to this design. We already have a working one. I'm looking for clarity on the odd behavior of the ComboBox itself.)
On to the code!
In the first example below, note how the data template is applied to everything in the dropdown, but the selected item area only uses a template if the selected item is not a ContentControl.
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="I am the template" Foreground="{Binding Foreground}" />
</DataTemplate>
</ComboBox.ItemTemplate>
<!-- Four 'Data' items for example only -->
<TextBlock Text="I am a Red TextBox" Foreground="Red"/>
<ListBox Foreground="Purple">
<ListBoxItem>I am a Purple ListBox</ListBoxItem>
</ListBox>
<ContentControl Content="I am a Blue ContentControl" Foreground="Blue" />
<Button Content="I am a Button with Green text" Foreground="Green" />
</ComboBox>
This second example shows that it is completely acceptable and fully supported to use a UIElement as the content of a ContentPresenter and still use a DataTemplate (via ContentTemplate) so you can use it in a purely-data role, allowing the template itself to define the visual appearance without displaying the UIElement itself, which is used purely as data here.
<ContentPresenter>
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBlock Text="I am the ContentTemplate" Foreground="{Binding Foreground}" />
</DataTemplate>
</ContentPresenter.ContentTemplate>
<ContentPresenter.Content>
<Button Content="I am the button" Foreground="Green" />
</ContentPresenter.Content>
</ContentPresenter>
Again, the issue is specific to a ComboBox. I want to find out why the data template isn't applied in that single case, and how to force it to be applied, if possible.
Of note, ComboBox does define SelectionBoxItemTemplate which is separate from the regular ItemTemplate but the rub is that is read-only so you can't set it. We really don't want to re-template the ComboBox as that can mess up proper theming.
Have you tried explicitly setting the DataTemplate to the ContentControl.ContentTemplate property?:
<UserControl.Resources>
<DataTemplate x:Key="DataTemplate">
<TextBlock Text="{Binding Content,
StringFormat='Displayed via template: {0}'}" />
</DataTemplate>
</UserControl.Resources>
...
<ContentControl Content="ContentControl"
ContentTemplate="{StaticResource DataTemplate}" />
I have a list (ListBox) of items in XAML using a StackPanel- based element template. The layout is fine, but I would now like to have a rectangle as a background for each item - creating a box around each one.
I was thinking of using a Canvas somehow, but as each item's height varies (as well as the height of the items inside the StackPanel), I'm not sure how to do it (I'm new to C#/XAML). What would be the best composition for the template in this situation?
You can just specify it in an ItemTemplate and it will do what you want, something like;
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderBrush="Red" BorderThickness="2" Background="Blue"/>
<!-- Insert the rest of your Item template stuff here -->
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
ListBox is a type of ItemsControl, which exposes several properties to control the appearance of the items. In this case, have a look at ItemContainerStyle (in the case of ListBox, the item containers are instances of ListBoxItem). You could, for instance, set the Background property in an ItemsContainerStyle to some color.
I am attempting to populate a ScrollerViewer control with an arbitrary number of of UserControls (Views) whilst using the MVVM pattern and bindings.
I am using an ObservableCollection to maintain my View collection and I have this collection set as the datacontext for my ScrollViewer control, however, getting the views to appear in the scroll viewer has had me going round in circles for a while now.
Can someone please point me to either a suitable example, or kindly provide an example which demonstrates the functionality I am attempting to achieve here?
Many thanks,
First off, I think you want an ItemsControl, not a ScrollViewer. Once you do that, assuming that your ObservableCollection of viewmodels is called "Items":
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<uc:MyControl DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Replace the <uc:MyControl DataContext="{Binding}"/> with a reference to your UserControl.
My problem is rather simple.
I have a ListBox, containing Thumnails (Image)
<ListBox Name="ListBox_Thumbnails" ItemsSource="{Binding}" DataContext="{Binding Source= {StaticResource ThumbnailListSource}}" Width="120" HorizontalAlignment="Left" Margin="-1,26,0,54">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Path=absolutePath}" MouseLeftButtonDown=<!--?????-->/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
I wanted to show an image, but as a new StackOverFlow user, I can't. You can find the image here:
http://www.freeimagehosting.net/uploads/61aa983cad.jpg
(For those who don't trust me, I explain here the content of the image:
On the left, there is a list of thumbnails (displayed vertically) and on the right there is a bigger image, corresponding per default to a large image of the first thumbnail).
When I click on a thumbnail (on the left), the large image on the right should be updated by the one that I clicked on.
As I am new with WPF, my approach is perhaps totally wrong with the ListBox.
Please, WPF Gurus, show me the light!
I guess, you can use events on ListBox, smth like SelectionChanged... but that's totally not the TRUE WPF-Jedi way -- remember, code-behind is the dark side! =)
Think data binding, that's the Force. Bind your large Image element's source to the SelectedItem property of the ListBox. It should look like
<Image Source="{Binding SelectedItem.absolutePath, ElementName=ListBox_Thumbnails}">
P.S. Every WPF-databinding-jedi should have this cheat sheet nearby.
P.P.S. Actually, as you're using ItemTemplate this might not work, you'll have your StackPanel as the selected item... in this case you can try the SelectedValuePath trick, set it to "absolutePath" and bind the large image to the SelectedValue property.
So your ListBox opening tag becomes:
<ListBox Name="ListBox_Thumbnails" ItemsSource="{Binding}" DataContext="{Binding Source= {StaticResource ThumbnailListSource}}" Width="120" HorizontalAlignment="Left" Margin="-1,26,0,54" SelectedValuePath="absolutePath">
And your large image tag becomes:
<Image Source="{Binding SelectedValue, ElementName=ListBox_Thumbnails}">