XAML/WPF Binding to Page.Resources - How does binding flow? - c#

I am attempting to use 2 DataTemplates to create something like this below:
I need a control that will allow for my dynamically built name-tags (chips per Material Design in XAML) to populate the blue boxed area stacking horizontally first then stacking vertically as each row fills up. Per my understanding a WrapPanel is what I need to use, I've found various examples and have attempted adapting them to fit my needs. I think I'm dang close with this one, but can't figure out what I'm missing here.
Per my understanding My ScrollViewer.ItemsControl should bring in my x:Key="Recipients" DataTemplate which should implement my x:Key="RecipientChip"DataTemplate for as many instances of Patient are in my IEnumerable<Patient> set called Patients.
I don't think I'm binding things correctly though because when I build, I see nothing printed. It's not throwing any errors in my output tab though so I'm not sure what's going on. My Patients IEnumeral is filled like an indexed object as expected. Can someone help me understand why my chips aren't showing up and how the flow of the bindings go? I feel like I'm passing Patients through my ScrollViewer.ItemsControll to the referenced Controls but maybe I'm just reading into this too much?
Here's my code:
XAML
<Page.Resources>
<DataTemplate x:Key="RecipientChip">
<StackPanel>
<materialDesign:Chip
Content="{Binding Patient.Name}">
<materialDesign:Chip.Icon>
<Image
Source="{Binding Patient.Image}" />
</materialDesign:Chip.Icon>
</materialDesign:Chip>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="Recipients">
<StackPanel>
<Label Content="Recipients:" Background="Gray" FontSize="16" />
<ItemsControl x:Name="Recipients" ItemsSource="{Binding Patients}" ItemTemplate="{StaticResource RecipientChip}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32*"/>
<ColumnDefinition Width="126*"/>
<ColumnDefinition Width="Auto" MinWidth="66.999"/>
<ColumnDefinition Width="193*"/>
<ColumnDefinition Width="32*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<materialDesign:Card
Background="{DynamicResource PrimaryHueLightBrush}"
Foreground="{DynamicResource PrimaryHueLightForegroundBrush}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2"
Grid.ColumnSpan="3"
Padding="8"
Margin="0,65,0,50">
<StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsControl ItemTemplate="{StaticResource Recipients}" />
</ScrollViewer>
</StackPanel>
</materialDesign:Card>
Code Behind:
public partial class EmailMessageView : Page
{
public EmailMessageView(Email email)
{
InitializeComponent();
Email = email;
Patients = email.Patients.Data;
EmailContent.NavigateToString(email.Content);
}
public Email Email;
public IEnumerable<Patient> Patients;
}
Patients
-[0] {Mable} NotificationLinkApp.Models.Patient
Address "9930 Somewhere St. " string
Age 18 double
+ Birthday {NotificationLinkApp.Models.CarbonDate} NotificationLinkApp.Models.CarbonDate
City "Anywhere" string
CommunicationId 3 int?
+ CreatedAt {NotificationLinkApp.Models.CarbonDate} NotificationLinkApp.Models.CarbonDate
Email "Mable.Lang#example.com" string
FirstName "Mable" string
Gender 1 int
HomePhone "555-555-4260" string
HomePhoneIsLandline null int?
Id 1490607 int
Image "pack://application:,,,/Resources/Images/user-unknown.png" string
IsEmail 1 int?
IsMail 1 int?
IsPhone 1 int?
IsReviewRequest 1 int?
IsText 1 int?
LanguageId 25493 int?
LastName "Lang" string
Latitude "40.527834" string
Longitude "-122.318749" string
Name "Mable Lang" string
OfficeId 2 int
ParentId null string
PreferredConfidential "" string
PreferredConfirm "" string
PreferredContact "" string
PreferredRecall "" string
ReferenceId "4634" string
SSN null string
State "New Mexico" string
+ UpdatedAt {NotificationLinkApp.Models.CarbonDate} NotificationLinkApp.Models.CarbonDate
WirelessPhone "555-555-4745" string
WorkPhone "555-555-3226" string
Zip "90134" string
_age 0 double
_email "Mable.Lang#example.com" string
_homePhone "555-555-4260" string
_image "" string
_wirelessPhone "555-555-4745" string
_workPhone "555-555-3226" string

In the end, I was able to get it to work by simplifying the code some as well as setting the DataContext to Patients. I continued to leverage the native functionality of a WrapPanel so that my "chips" would stack horizontally and wrap to a new line much like text. Here is the working code.
XAML
<Page.Resources>
<DataTemplate x:Key="RecipientChip">
<StackPanel>
<materialDesign:Chip
Background="#FFFFFFFF"
Content="{Binding Name}" Click="Chip_Clicked">
<materialDesign:Chip.Icon>
<Image
Source="{Binding Image}" />
</materialDesign:Chip.Icon>
</materialDesign:Chip>
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32*"/>
<ColumnDefinition Width="126*"/>
<ColumnDefinition Width="Auto" MinWidth="66.999"/>
<ColumnDefinition Width="193*"/>
<ColumnDefinition Width="32*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<materialDesign:Card
Background="{DynamicResource PrimaryHueLightBrush}"
Foreground="{DynamicResource PrimaryHueLightForegroundBrush}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2"
Grid.ColumnSpan="3"
Padding="8"
Margin="0,65,0,50">
<StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<StackPanel>
<Label Content="Recipients:" FontSize="16" />
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{StaticResource RecipientChip}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</StackPanel>
</materialDesign:Card>
<WebBrowser Name="EmailContent" Grid.Row="1" Grid.Column="1" Grid.RowSpan="5" Grid.ColumnSpan="3" Margin="0,52,0,10"/>
</Grid>
Code Behind
public EmailMessageView(Email email)
{
InitializeComponent();
Email = email;
Patients = email.Patients.Data;
EmailContent.NavigateToString(email.Content);
DataContext = Patients;
}
public Email Email;
public IEnumerable<Patient> Patients;

Related

How to add multiple elements to the wrappanel?

I am trying to insert several StackPanel inside the WrapPanel as you can see the XAML below:
Only the TextBlock inside the StackPanel will be modified so as not to repeat the Title and Text.
<Window x:Class="ambient_test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ambient_test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ScrollViewer CanContentScroll="True">
<WrapPanel x:Name="wrappanel">
<StackPanel x:Name="panel1" Width="120" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background="#FF38C59F"></StackPanel>
<TextBlock Grid.Row="2" Text="Title 1" Foreground="LightGray" VerticalAlignment="Top" TextAlignment="Center"/>
<TextBlock Grid.Row="1" Text="Text 1" Foreground="#FF747474" TextAlignment="Center" Margin="0 15 0 0"/>
</Grid>
</StackPanel>
<StackPanel x:Name="panel2" Width="120" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background="#FF38C59F"></StackPanel>
<TextBlock Grid.Row="2" Text="Title 2" Foreground="LightGray" VerticalAlignment="Top" TextAlignment="Center"/>
<TextBlock Grid.Row="1" Text="Text 2" Foreground="#FF747474" TextAlignment="Center" Margin="0 15 0 0"/>
</Grid>
</StackPanel>
</WrapPanel>
</ScrollViewer>
</Grid>
</Window>
I created a class called Info to change the Title and the Text. In the method constructor I have a for loop that will add 10 contents to the List.
public MainWindow()
{
InitializeComponent();
List<Info> infos = new List<Info>();
for (int i = 0; i < 10; i++)
{
infos.Add(new Info()
{
Title = $"title {i}",
Text = $"text {i}"
});
}
}
public class Info
{
public string Title { get; set; }
public string Text { get; set; }
}
For example, my List has 100 records, so I need to add 100 StackPanel inside my WrapPanel following the same Title and Text as the List.
Is there any way to do this? For example using Binding?
You would use an ItemsControl that uses a WrapPanel as its ItemsPanel, and defines the layout of the items by an appropriate DataTemplate:
<ItemsControl x:Name="itemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Title}" .../>
<TextBlock Grid.Row="1" Text="{Binding Text}" .../>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
and assign the List<Info> to its ItemsSource property:
itemsControl.ItemsSource = infos;

Xamarin : Adding multiple bindings to multiple collection views on the same page

I am currently trying to build two separate collection views on the same page in Xamarin. I keep getting the error that content is set more than once and also that I've set the content binding more than once. How do I add different bindings to two separate collection views on the same page?
ConsumerOrders.xaml page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewmodels="clr-namespace:Shared.ViewModel"
mc:Ignorable="d"
x:Class="Shared.consumerOrders">
<ContentPage.BindingContext>
<viewmodels:AddedServicesViewModel />
</ContentPage.BindingContext>
<d:ContentPage.BindingContext>
<viewmodels:PastOrderViewModel />
</d:ContentPage.BindingContext>
<ScrollView>
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Services added" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView ItemsSource="{Binding ViewQuoteStatus}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<!--0-->
<RowDefinition Height="30"/>
<!--1-->
<RowDefinition Height="20"/>
<!--2-->
<RowDefinition Height=".25"/>
<!--3-->
<RowDefinition Height="4"/>
<!--4-->
<RowDefinition Height="Auto"/>
<!--5-->
<RowDefinition Height="Auto"/>
<!--6-->
<RowDefinition Height=".25"/>
<!--7-->
<RowDefinition Height="Auto"/>
<!--8-->
<RowDefinition Height="Auto"/>
<!--9-->
<RowDefinition Height=".25"/>
<!--10-->
<RowDefinition Height="Auto"/>
<!--11-->
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4"/>
</Grid.ColumnDefinitions>
<Label Text="Past Orderrs" FontAttributes="Bold" TextColor="#F65506" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" VerticalTextAlignment="End" HorizontalTextAlignment="Start" FontSize="18"/>
<Label Grid.Column="1" Grid.Row="7" BackgroundColor="#707070" Grid.ColumnSpan="3"/>
<!--This is a line-->
<BoxView BackgroundColor="#F0F0F0" Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="3" CornerRadius="22"/>
<Label Grid.Column="1" Grid.Row="9" Padding="10" TextColor="Black" FontSize="18" Text="{Binding BusinessName}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" Grid.ColumnSpan="2"/>
<Label Grid.Column="3" Grid.Row="9" Padding="0,0,20,0" TextColor="#F65506" FontAttributes="Bold" FontSize="18" Text="View" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand" Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ScrollView>
</ContentPage>
AddedServicesViewModel.cs :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class AddedServicesViewModel
{
readonly IList<AddedServiceStatus> source;
public ObservableCollection<AddedServiceStatus> ViewAddedServices { get; private set; }
public AddedServicesViewModel()
{
source = new List<AddedServiceStatus>();
CreateAddedServicesCollection();
}
void CreateAddedServicesCollection()
{
source.Add(new AddedServiceStatus
{
BusinessName = "Duck's Duct Cleaning"
});
source.Add(new AddedServiceStatus
{
BusinessName = "Rodney's Home Repair"
});
ViewAddedServices = new ObservableCollection<AddedServiceStatus>(source);
}
}
}
PastOrderViewModel :
using Shared.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Shared.ViewModel
{
class PastOrderViewModel
{
readonly IList<PastOrderStatus> source;
public ObservableCollection<PastOrderStatus> ViewPastOrders { get; private set; }
public PastOrderViewModel()
{
source = new List<PastOrderStatus>();
CreatePastOrderCollection();
}
void CreatePastOrderCollection()
{
source.Add(new PastOrderStatus
{
BusinessName = "Karen's Magnificent Dog Grooming"
});
source.Add(new PastOrderStatus
{
BusinessName = "Harry's In Home Haircuts"
});
source.Add(new PastOrderStatus
{
BusinessName = "Shelly's Floral Arrangements"
});
ViewPastOrders = new ObservableCollection<PastOrderStatus>(source);
}
}
}
You could also bind a ViewModel to each CollectionView separately.
like:
<CollectionView ItemsSource="{Binding ViewAddedServices}">
<CollectionView.BindingContext>
<viewmodels:AddedServicesViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
<CollectionView ItemsSource="{Binding ViewPastOrders}">
<CollectionView.BindingContext>
<viewmodels:PastOrderViewModel/>
</CollectionView.BindingContext>
...
</CollectionView>
You can't have two ViewModels binding to a SingleView. (as far a I know)
I see that the DataTemplate in both Collections are the same..... there are many ways to refactor....
You could create two CustomView one with the AddedServicesViewModel and the other with PastOrderViewModel
You can merge the two ViewModels into one, and create a CustomView that it's the collection.
Another thing that I see that It could not work is that you can't have a more than one View Nested in a ScrollView
<ScrollView>
<StackLayout> /* Or any other Layout, Grid, Absolute, Flex etc... */
</StackLayout>
</ScrollView>
Another thing is that a CollectionView with orientation vertical in a ScrollView maybe it won't behave as you expect, since the CollectionView with orientation vertical it has Scroll
Two CollectionViews with orientation vertical in the same View it should have a Height, I would do something like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<CollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </CollectionView>
<CollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </CollectionView>
</Grid>
or if you create a custom view (custom control)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<MyCustomCollectionView Grid.Row="0" ItemsSource="{Binding ViewQuoteStatus}"> ... </MyCustomCollectionView>
<MyCustomCollectionView Grid.Row="1" ItemsSource="{Binding ViewAddedServices}"> ... </MyCustomCollectionView>
</Grid>

Can't use windowManager.ShowWindow() with Caliburn.Micro

I'm currently developing a plugin for Revit (BIM software) and I'm, trying to use WPF and Caliburn.Micro to show a window/dialog when I press a button of the plugin.
So like in the documentation, I have a bootstrapper:
public class Bootstrapper : BootstrapperBase
{
public Bootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<LocationPopupViewModel>();
}
}
}
A simple testing ViewModel:
namespace ExternalForms.ViewModels
{
public class LocationPopupViewModel : Screen
{
private int _horizontalLength;
private int _verticalLength;
public int HorizontalLength
{
get
{
return _horizontalLength;
}
set
{
_horizontalLength = value;
NotifyOfPropertyChange(() => HorizontalLength);
}
}
public int VerticalLength
{
get
{
return _verticalLength;
}
set
{
_verticalLength = value;
NotifyOfPropertyChange(() => VerticalLength);
}
}
}
}
And of course the window that I want to show:
<Window x:Class="ExternalForms.Views.LocationPopupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ExternalForms.Views"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
ResizeMode="CanResizeWithGrip"
Title="gebied" Height="300" Width="410"
FontSize="16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<!--Row 1-->
<TextBlock Text="Stel xxx in" FontWeight="DemiBold" Grid.Column="1" Grid.Row="1" FontSize="18"/>
<!--Row 2-->
<StackPanel Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Width="360" Margin="0, 0, 0, 20">
<TextBlock TextWrapping="Wrap">
Let op dat het gebied een maximale horizontale en verticale lengte mag hebben van 1 kilometer.
</TextBlock>
</StackPanel>
<!--Row 3-->
<TextBlock Text="Horizontaal" Grid.Column="1" Grid.Row="3"/>
<!--Row 4-->
<TextBox x:Name="HorizontalLength" Grid.Row="4" Grid.Column="1" MinWidth="100"/>
<!--Row 5-->
<TextBlock Text="Verticaal" Grid.Column="1" Grid.Row="5"/>
<!--Row 6-->
<TextBox x:Name="VerticalLength" Grid.Row="6" Grid.Column="1" MinWidth="100"/>
<!--Row 7-->
<StackPanel Orientation="Horizontal" Grid.Row="7" Grid.Column="1" Margin="0, 20, 0, 0" Grid.ColumnSpan="2" HorizontalAlignment="Right">
<Button x:Name="SubmitDimensions" IsDefault="True" Width="100" Height="30">OK</Button>
<Button IsCancel="True" IsDefault="True" Width="100" Height="30">Cancel</Button>
</StackPanel>
</Grid>
The function that is trying to show the window:
private void SetBoundingBox()
{
IWindowManager windowManager = new WindowManager();
LocationPopupView locationPopup = new LocationPopupView();
windowManager.ShowWindow(locationPopup, null, null);
}
But when I try to open the dialog in Revit, a window with an error pops up:
UPDATE:
My current project structure looks like this:
Assembly "UI" takes care of all the internal UI elements in Revit (so the buttons in Revit, even though there is currently only one).
The current button in Revit calls the "Get3DBAG" assembly, who does some tasks and eventually calls the "Location" assembly, which calls the Windowmanager.showwindow() method for the WPF views, which are in the "ExternalForms" assembly.
You problem lies in the following line.
LocationPopupView locationPopup = new LocationPopupView();
You are attemping to initialize an instance of View, instead of ViewModel. You should replace this with following.
LocationPopupViewModel locationPopup = new LocationPopupViewModel();
Caliburn Micro would resolve the corresponding View by itself using the naming convention.
Update : Based on Comment
From your comment, it looks like your View/ViewModels are in a different assembly. In that scenario, you need to ensure the assembly is included while Caliburn Micro searches for Views. You can do so by overriding SelectAssemblies method in Bootstrapper.
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[]
{
Assembly.GetExecutingAssembly()
// Ensure your external assembly is included.
};
}
You would be also interested to read more Custom Conventions using Caliburn Micro

WPF layout created dynamically using MVVM

I'm trying to postion views to the window in layout which is rectangle base while using MVVM pattern.
In WinForms I was able to use width, height, x and y of rectagle to position controls easily by just setting same properties on control.
Now I'm rewriting this code to wpf using MVVM and I'm lost.
this is what I'm trying to do:
This is something I thought might work but it does not.
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding VirtualScreens}" Grid.IsSharedSizeScope="True" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Grid.Row="{Binding Row}" Grid.Column="{Binding Column}" Content="{Binding Name}"></Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
public class VirtualScreen : ObservableObject
{
string name;
int row;
int column;
public string Name
{
get { return name; }
set
{
name = value;
RaisePropertyChanged(() => Name);
}
}
public int Row
{
get { return row; }
set
{
row = value;
RaisePropertyChanged(() => Row);
}
}
public int Column
{
get { return column; }
set
{
this.column = value;
RaisePropertyChanged(() => Column);
}
}
}
Thank you for any type of help
you could use ItemsControl ItemsPanel, ItemsTemplate and ItemContainerStyle.
Here is an example for you
<ItemsControl ItemsSource="{Binding VirtualScreens}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Style.Setters>
<Setter Property="Grid.Row" Value="{Binding Row}" />
<Setter Property="Grid.Column" Value="{Binding Column}" />
</Style.Setters>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
You can use a WPF Grid to layout the elements as shown in your UI. A three-row, three-column grid would work fine for you:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Grid.RowSpan="2">This is the big top left section</Button>
<Button Grid.Row="1" Grid.Column="2">Top right</Button>
<Button Grid.Row="2" Grid.Column="2">Middle right</Button>
<Button Grid.Row="3" Grid.Column="1">Bottom left</Button>
<Button Grid.Row="3" Grid.Column="2">Bottom center</Button>
<Button Grid.Row="3" Grid.Column="2">Bottom right</Button>
</Grid>
Checkout Grid Row and Column Spanning for more info.

How to bind dictionary key with the listbox textblock?

I've got a problem get binding working in an DataTemplate of a ListView. My binding target is a KeyValuePair.
this is MY XAML Code:-
<ListBox x:Name="ListBox_Setting" ItemsSource="{Binding DictTemperature}" BorderBrush="Black" BorderThickness="1" Height="582" Width="300">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="78">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="Img_ListSetting" Width="50" Height="50" Source="/Assets/un-checked.png" Margin="18,7,507,21" />
<TextBlock x:Name="Tb_ListSetting" Text="{Binding Path=Key}" FontFamily="OpenSans" FontSize="30" Margin="89,0,18,20" Height="42" VerticalAlignment="Bottom" />
<Rectangle x:Name="Line_ListSetting" Height="1" Margin="15,66,15,11" Fill="#FF3498DB"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And This is My C# Code :-
public Dictionary<string, bool> DictTemperature { set; get; }
DictTemperature = new Dictionary<string, bool>();
if (!appSettings.Contains("AppTemperature"))
{
DictTemperature.Add("Celsius", true);
DictTemperature.Add("Fahrenheit", true);
DictTemperature.Add("Kelvin", true);
DictTemperature.Add("Rankine", true);
appSettings.Add("AppTemperature", DictTemperature);
}
DictTemperature = (Dictionary<string, bool>)appSettings["AppTemperature"];
here listbox is showing count as 4 and showing the key value pairs also but unable to bind key with the textblock.
Please tell me the solution....
You can do it Shown here (Binding a Dictionary's key and value in a listbox with wpf)

Categories