I am working on a WPF Project with Caliburn Micro. Please consider the following code snippets:
PopupWindowView.xaml
<Window x:Class="PTSRDesktopUI.Views.PopupWindowView"
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:PTSRDesktopUI.Views"
mc:Ignorable="d" ShowInTaskbar="True"
ResizeMode="NoResize" SizeToContent="Height" FontSize="24"
MouseDown="Window_MouseDown" Background="#FFF7F7F7" Icon="/Images/infoicon_8Ve_icon.ico"
Title="Pfad Info" Height="300" Width="500">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock FontSize="20" Grid.Column="1" Text="{Binding Path=Path}" Margin="10 10 10 10"
HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="False"
FontFamily="Segoe UI Light"/>
</Grid>
</Window>
PopupWindowViewModel.cs
using Caliburn.Micro;
using PTSRDesktopUI.Models;
namespace PTSRDesktopUI.ViewModels
{
public class PopupWindowViewModel : Screen
{
private string _path;
public PopupWindowViewModel(ChangesModel model)
{
_path = model.ParameterPfad;
}
public string Path
{
get { return _path; }
set
{
_path = value;
NotifyOfPropertyChange(() => Path);
}
}
}
}
OverviewView.xaml
<DataGridTemplateColumn CellStyle="{StaticResource DataGridCellCentered}" Header="Info">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button BorderThickness="0" Height="30" Width="30"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
cal:Message.Attach="ShowPath($this)">
<Image Source="/Images/infoicon.png"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
OverviewViewModel.cs
private readonly IWindowManager manager = new WindowManager();
public void ShowPath(ChangesModel model)
{
manager.ShowWindow(new PopupWindowViewModel(model), null, null);
}
All this does is, when the Button in the DataGrid is pressed, the PopupWindow pops up and displays some data. It all works fine. The only thing I cannot seem to figure out is how to display the new PopupWindow at the same location where the clicked Button is, or rather where my mouse pointer is. I have read all the other StackOverflow questions regarding this problem but none of them does the trick for me. I either get an error or it just does not work. Anyone has any ideas how to solve this?
Related
I'm making an application using Caliburn.Micro(for easy data binding and stuff) and MahApps.Metro(for designing).
I've created a View name 'MainView' which has HamburgerMenu of MahApps.
My issue is data binding is working fine under HamburgerMenu.ContentTemplate tag
Here is my HamburgerMenu.ContentTemplate xaml.
<Page x:Class="Sample.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:utils="clr-namespace:Omni.WindowsClient.Utils"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Omni.WindowsClient.Views"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="600">
<Page.Resources>
<DataTemplate x:Key="HamburgerMenuItem"
DataType="{x:Type mah:HamburgerMenuItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Margin="12"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="{Binding Glyph}"
Stretch="UniformToFill" />
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Label}" />
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<mah:HamburgerMenu x:Name="HamburgerMenuControl"
SelectedIndex="0"
ItemTemplate="{StaticResource HamburgerMenuItem}"
OptionsItemTemplate="{StaticResource HamburgerMenuItem}"
IsPaneOpen="True"
DisplayMode="CompactInline"
cal:Message.Attach="[Event ItemClick] = [Action ShowDetails(HamburgerMenuControl.SelectedItem)]"
DataContext="{Binding RelativeSource={RelativeSource self}}">
<mah:HamburgerMenu.ItemsSource>
<mah:HamburgerMenuItemCollection>
<mah:HamburgerMenuItem Label="System Status">
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Tasks" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
<mah:HamburgerMenuItem Label="Inbox">
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Inbox" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Certificate" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
</mah:HamburgerMenuItemCollection>
</mah:HamburgerMenu.ItemsSource>
<mah:HamburgerMenu.ContentTemplate>
<DataTemplate DataType="{x:Type mah:HamburgerMenuItem}">
<Grid utils:GridUtils.RowDefinitions="48,*">
<!--cal:Action.TargetWithoutContext="{Binding ElementName=HamburgerMenuControl, Path=DataContext}"-->
<Border Grid.Row="0"
Background="{DynamicResource MahApps.Metro.HamburgerMenu.PaneBackgroundBrush}">
<TextBlock x:Name="Header"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="24"
Foreground="White" />
<!--Text="{Binding Path=Header, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"-->
</Border>
<Frame Grid.Row="1"
cal:Message.Attach="RegisterFrame($source)"
DataContext="{x:Null}"
NavigationUIVisibility="Hidden" />
</Grid>
</DataTemplate>
</mah:HamburgerMenu.ContentTemplate>
</mah:HamburgerMenu>
</Grid>
</Page>
and respective view model code is:
using Caliburn.Micro;
using MahApps.Metro.Controls;
using System.Windows.Controls;
namespace Sample.ViewModels
{
public class MainViewModel : Screen
{
private readonly SimpleContainer _container;
private INavigationService _navigationService;
private string _header;
public string HeaderTitle
{
get { return _header; }
set
{
_header = value;
NotifyOfPropertyChange();
}
}
public MainViewModel(SimpleContainer container)
{
this._container = container;
DisplayName = "Main";
}
public void RegisterFrame(Frame frame)
{
_navigationService = new FrameAdapter(frame);
_container.Instance(_navigationService);
_navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
HeaderTitle = "System Status";
}
public void ShowDetails(HamburgerMenuItem menuItem)
{
switch (menuItem.Label)
{
case "System Status":
_navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
HeaderTitle = "System Status";
break;
case "Inbox":
_navigationService.NavigateToViewModel(typeof(InboxViewModel));
HeaderTitle = "Inbox";
break;
default:
break;
}
}
}
}
I want to change View in frame under HamburgerMenu.ContentTemplate when I click on menu item.
Like System Status view is SystemStatusView
and Inbox view is InboxView.
My code is working fine (it changes the view in frame and change the Header label too) if I don't use HamburgerMenu.ContentTemplate. But I want to use HamburgerMenu.ContentTemplate to work with HamburgerMenu.
Thanks!
If it's working fine if you don't use HamburgerMenu.ContentTemplate, but stops working when you do, the problem is probably with you overwriting the default template in a way that doesn't support all functionalities of a control.
I'd suggest you to use Blend to get the default HamburgerMenu.ContentTemplate, then just edit it to your needs, without changing too much (keep in mind that names of controls used as a template may have a crucial meaning, so be careful what you are editing).
If you don't know how to use Blend to get your control's template, here is a simple tutorial described in a documentation of Telerik controls (don't worry, it works the same for all controls). You just need to create copy of a HamburgerMenu.ContentTemplate, paste it to your application and you are good to go (editing).
I'm trying to create a little tool for Microsofts Team Founation Server (which is not that important for the question). However i'm not that familiar with C# and WPF and even after reading through some tutorials about bindings and resources, i can't figure out, how to get the code working.
With the Visual Studio Designer i created a little form, that just has some buttons and a textbox that should display the name of the authorized user.
Unfortunately, after logging in, an ArgumentException is thrown. So the question is : How can i bind my local TfsTeamProjectCollection to tfsTeamProjectCollectionViewSource?
Thanks for your help!
<Window
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:TFSBranchingTool"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:Client="clr-namespace:Microsoft.TeamFoundation.Client;assembly=Microsoft.TeamFoundation.Client" x:Class="TFSBranchingTool.MainWindow"
mc:Ignorable="d"
Title="TFSBranchingTool" Height="360" Width="560"
x:Name="wnd" Loaded="wnd_Loaded">
<Window.Resources>
<CollectionViewSource x:Key="tfsTeamProjectCollectionViewSource" d:DesignSource="{d:DesignInstance {x:Type Client:TfsTeamProjectCollection}, CreateList=True}" Source="{Binding}"/>
</Window.Resources>
<Grid Margin="0,0,0,-1">
<Menu x:Name="menu" VerticalAlignment="Top" Background="{DynamicResource {x:Static SystemColors.MenuBrushKey}}" d:IsLocked="True">
<MenuItem Header="File">
<MenuItem Header="Exit" HorizontalAlignment="Left" Click="exit_application_click"/>
</MenuItem>
<MenuItem Header="Team">
<MenuItem Header="Connect to server" HorizontalAlignment="Left" Margin="0" Width="201" Click="connect_to_server_click"/>
</MenuItem>
</Menu>
<StatusBar x:Name="statusbar" VerticalAlignment="Bottom" Margin="0,0,0,-2" MinHeight="16">
<StatusBarItem x:Name="connection_status" Content="{Binding TeamProjectCollection.AuthorizedIdentity.DisplayName}" HorizontalAlignment="Left"/>
</StatusBar>
<Grid x:Name="grid1" DataContext="{StaticResource tfsTeamProjectCollectionViewSource}" HorizontalAlignment="Left" Margin="138,122,0,0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Display Name:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="displayNameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding AuthorizedIdentity.DisplayName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
</Grid>
</Grid>
And here is the logic:
using Microsoft.TeamFoundation.Client;
using System.Windows;
namespace TFSBranchingTool
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private TfsTeamProjectCollection m_tfs_team_project_collection;
public MainWindow()
{
InitializeComponent();
}
private void exit_application_click(object sender, RoutedEventArgs e)
{
Close();
}
private void connect_to_server_click(object sender, RoutedEventArgs e)
{
TeamProjectPicker team_project_picker = new TeamProjectPicker(TeamProjectPickerMode.NoProject, false);
if (team_project_picker.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
m_tfs_team_project_collection = team_project_picker.SelectedTeamProjectCollection;
System.Windows.Data.CollectionViewSource tfsTeamProjectCollectionViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("tfsTeamProjectCollectionViewSource")));
//ArgumentException :
//Additional Information: "<TFS-URI>" is an invalid value for the property "Source".
tfsTeamProjectCollectionViewSource.Source = m_tfs_team_project_collection;
}
}
}
}
You have to use GetDefaultView static Method of CollectionViewSource class to give the view your collection.
Here is what you have to do.
tfsTeamProjectCollectionViewSource.Source = CollectionViewSource.GetDefaultView(m_tfs_team_project_collection);
Also you haven't set the data context of the window as Window itself.
Try doing this.
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
By doing the above, any binding in the xaml code will look for its source in the window.
Another thing I have found wrong in your code is that you have defined
tfsTeamProjectCollectionViewSource as a local variable rather than a data member of the Window.
Try making it a data member like m_tfs_team_project_collection and then see what happens.
I've created a simple custom messagebox that automatically scales depending on the length of the text to be displayed :
public partial class CustomMessageBox : Window
{
public CustomMessageBox(string title, string text)
{
InitializeComponent();
ResizeMode = ResizeMode.NoResize;
label.Content = text;
Title = title;
}
public static void Show(string title, string text)
{
CustomMessageBox box = new CustomMessageBox(title, text);
box.SizeToContent = SizeToContent.WidthAndHeight;
box.ShowDialog();
}
private void button_Click(object sender, RoutedEventArgs e)
{
Close();
}
}
This works nicely however my button is clamping to the bottom side of the window because the window automatically scales :
And the button seems to be moving once the message gets longer :
How would I make sure the button stays centered and have a margin of around 10px from the bottom so it doesn't look that clamped?
I tried to set the Margin manually but that doesn't seem to work.
XAML (largely generated by the designer) :
<Window x:Class="RapidEvent.CustomMessageBox"
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:RapidEvent"
mc:Ignorable="d"
Background="{DynamicResource WindowBackgroundBrush}"
Title="" Height="Auto" Width="Auto">
<Grid>
<StackPanel>
<Label x:Name="label" Content="" HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Top" FontSize="13px" RenderTransformOrigin="0.392,0.486"/>
<Button x:Name="button" x:FieldModifier="public" IsDefault="True" Content="_Ok" HorizontalAlignment="Left" Margin="110,40,0,0" VerticalAlignment="Top" Width="80" Height="21" Click="button_Click"/>
</StackPanel>
</Grid>
</Window>
Simply change your StackPanel to a Grid and the HorizonalAlignment of your button to Center and take off all but the bottom margin. You'll also need to set the VerticalAlignment to Bottom. You also need to put the button on row 1.
This way the button will be clamped to the bottom of the dialog and always centred.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label x:Name="label" Content=""
HorizontalAlignment="Left" Margin="10,0,0,0"
VerticalAlignment="Top" FontSize="13px"
RenderTransformOrigin="0.392,0.486"/>
<Button Grid.Row="1" x:Name="button" x:FieldModifier="public"
IsDefault="True" Content="_Ok"
HorizontalAlignment="Center" Margin="0,0,0,20"
VerticalAlignment="Bottom" Width="80" Height="21"/>
</Grid>
Use grid instead of StackPanel:
<Grid >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<telerik:Label x:Name="label" Content="LSFFD" HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Top" FontSize="13px" RenderTransformOrigin="0.392,0.486"/>
<Button Grid.Row="1" x:Name="button" x:FieldModifier="public" Content="_Ok" HorizontalAlignment="Center" Margin="0 0 0 10" VerticalAlignment="Bottom" Width="80" Height="21" Click="button_Click"/>
</Grid>
In our C# WPF application (with the Caliburn.Micro framework) we have a View and a ViewModel. In the ViewModel we have a string-property and I want to show this string inside each child of an ItemsControl (these items have their own ViewModel). I know I could just pass the property to each of these items, but that shouldn't be needed.
So, here is the relevant part of the ViewModel:
using System;
...
namespace NatWa.MidOffice.Modules.Financien.Views
{
public class BankgarantieFinancienOpsplitsenViewModel : ValidationBase<BankgarantieFinancienOpsplitsenViewModel>
{
...
public BankgarantieFinancienOpsplitsenViewModel(BankgarantieFinancienState state, ...)
{
...
Dossiernummer = state.Dossiernummer;
Kopers = state.Kopers.Select(k =>
{
var bfkvm = new BankgarantieFinancienKoperViewModel(k, adresService);
bfkvm.ObservePropertyChanged(koper => koper.Bedrag).Subscribe(p => CalculateOpenstaandBedrag());
return bfkvm;
}).ToList();
...
}
public string Dossiernummer
{
get { return _dossiernummer; }
private set
{
if (value == _dossiernummer) return;
_dossiernummer = value;
NotifyOfPropertyChange(() => Dossiernummer);
}
}
...
}
}
The relevant part of the View:
<Window x:Class="NatWa.MidOffice.Modules.Financien.Views.BankgarantieFinancienOpsplitsenView"
...>
<Grid Style="{StaticResource WindowPaddingStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
...
</Grid.RowDefinitions>
...
<ItemsControl x:Name="Kopers" Grid.Row="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{StaticResource BorderBrush}" BorderThickness="1" Margin="0,3" Padding="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
...
<StackPanel Grid.Column="1" Orientation="Vertical">
...
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0,3" HorizontalAlignment="Right">
...
<!-- THIS IS WHERE I WANT TO DISPLAY THE DOSSIERNUMMER-PROPERTY OF THE PARENT VIEWMODEL -->
<TextBlock Text="{Binding ??Parent??.Dossiernummer}"/>
...
</StackPanel>
...
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
</Grid>
</Window>
I did try to replace the TextBox with the following, based on this SO-answer, but to now result:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Dossiernummer}"/>
I've also tried to add the DataContext binding to the Window (even though Caliburn.Micro should do this automatically):
<Window x:Class="NatWa.MidOffice.Modules.Financien.Views.BankgarantieFinancienOpsplitsenView"
...
DataContext="{Binding}">
Ok, problem found.. >.>
Me and a co-worker tried a couple of more things, like:
Adding this to the window:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignData BankgarantieFinancienOpsplitsenViewModel}" mc:Ignorable="d"
Changing the TextBlock-binding to:
<TextBlock Text="{Binding ElementName=Kopers, Path=DataContext.Dossiernummer}"/>
and a couple of more things, all to no avail.. In a couple of other Views we've used the exact same things with success, so we had no idea what could be wrong. And then it struck us..
So, what was the problem? The string in the property was null for the ViewModel I was testing this for.... Great start of the day to make such a stupid mistake.. So, we've changed setting the value in the ViewModel to this:
Dossiernummer = state.Dossiernummer ?? state.UbizzDossiernummer;
(The UbizzDossiernummer is the number of the old system we are replacing (which we've imported into our appliction), and the Dossiernummer are the new numbers from Objects made in our application. The object I've been testing this for was an imported one..)
So, I've changed it back to:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Dossiernummer}"/>
and it works..
I've created some UserControls which are wrapping some standard controls, for example: a textbox/combobox + Image + textblock. I'm trying to do the same thing with AutoCompleteBox and have failed so far...
The list of items is shown fine, I can select na item, but that doesn't trigger a change to the SelectedItem. I'm using almost the same code for combobox so not sure what's wrong...
Anyway I've played around with ValueMemberPath / ValueMemberBinding on the AutoCompleteBox but not sure if that's the way to go.
The UserControl xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Margin="0,0,2,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ElementName=ACProperty, Path=ImageSource}" VerticalAlignment="Center"
MaxHeight="30" MaxWidth="30" Margin="1" Grid.Column="0" RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock Text="{Binding ElementName=ACProperty, Path=Label}" VerticalAlignment="Center"
HorizontalAlignment="Left" Grid.Column="1" Margin="1" TextWrapping="Wrap" Width="100" />
</Grid>
<toolkitInput:AutoCompleteBox FilterMode="ContainsOrdinal" IsTextCompletionEnabled="True"
ItemsSource="{Binding ElementName=ACProperty, Path=ItemsSource}"
SelectedItem="{Binding ElementName=ACProperty, Path=SelectedItem}"
MinimumPrefixLength="2"
MinimumPopulateDelay="300"
VerticalAlignment="Center"
HorizontalAlignment="Stretch" Grid.Column="1" Margin="1,1,2,1" />
</Grid>
The code behind:
public static DependencyProperty LabelProperty = DependencyProperty.Register(
"Label", typeof(string), typeof(AutoCompleteProperty));
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(object), typeof(AutoCompleteProperty));
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(AutoCompleteProperty),
new FrameworkPropertyMetadata() { BindsTwoWayByDefault = true });
public static DependencyProperty ImageSourceProperty = DependencyProperty.Register(
"ImageSource", typeof(string), typeof(AutoCompleteProperty));
public object ItemsSource
{
get
{
return (object)GetValue(ItemsSourceProperty);
}
set
{
SetValue(ItemsSourceProperty, value);
}
}
public object SelectedItem
{
get
{
return (object)GetValue(SelectedItemProperty);
}
set
{
SetValue(SelectedItemProperty, value);
}
}
public string Label
{
get
{
return (string)GetValue(LabelProperty);
}
set
{
SetValue(LabelProperty, value);
}
}
public string ImageSource
{
get
{
return (string)GetValue(ImageSourceProperty);
}
set
{
SetValue(ImageSourceProperty, value);
}
}
And in a UserControl/Window where I would like to use it:
<cont:AutoCompleteProperty Label="Product Category"
ItemsSource="{Binding Path=ProductCategories}"
SelectedItem="{Binding Path=ProductCategory}"
ImageSource="..."/>
I have updated binding in the following code....
<UserControl x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="350" Width="525"
xmlns:toolkitInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
x:Name="root"
>
<Grid>![enter image description here][1]
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Margin="0,0,2,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageSource,ElementName=root}" VerticalAlignment="Center" MaxWidth="100" Margin="1" Grid.Column="0" RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock Text="{Binding Label,ElementName=root}" DataContext="{Binding RelativeSource={RelativeSource Self}}" VerticalAlignment="Center"
HorizontalAlignment="Left" Grid.Column="1" Margin="1" TextWrapping="Wrap" Width="100" />
</Grid>
<toolkitInput:AutoCompleteBox FilterMode="ContainsOrdinal" IsTextCompletionEnabled="True"
ItemsSource="{Binding ItemsSource,ElementName=root}"
SelectedItem="{Binding SelectedItem,ElementName=root}"
MinimumPrefixLength="2"
MinimumPopulateDelay="300"
VerticalAlignment="Center"
HorizontalAlignment="Stretch" Grid.Column="1" Margin="1,1,2,1" />
</Grid>
</UserControl>
Here is a image of the window using the above code
I made few changes in your bindings.
Observe usercontrol DataContext.
<UserControl x:Class="WpfApplication1.AutoCompleteProperty"
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"
mc:Ignorable="d"
xmlns:toolkitInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Margin="0,0,2,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageSource}" VerticalAlignment="Center" MaxWidth="100" Margin="1" Grid.Column="0" RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock Text="{Binding Label}" VerticalAlignment="Center"
HorizontalAlignment="Left" Grid.Column="1" Margin="1" TextWrapping="Wrap" Width="100" />
</Grid>
<toolkitInput:AutoCompleteBox FilterMode="ContainsOrdinal" IsTextCompletionEnabled="True"
ItemsSource="{Binding ItemsSource}"
SelectedItem="{Binding SelectedItem}"
MinimumPrefixLength="2"
MinimumPopulateDelay="300"
VerticalAlignment="Center"
HorizontalAlignment="Stretch" Grid.Column="1" Margin="1,1,2,1" />
</Grid>
</UserControl>
and no changes in code behind file