I have a class which implements inotifypropertychaned.
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name = string.Empty;
public string Name
{
get
{
return _name;
}
set
{
this._name = value;
onPropertyChanged(this, "Name");
}
}
private void onPropertyChanged(object sender, string property)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(sender, new PropertyChangedEventArgs(property));
}
}
}
here in UI i ve a textbox where a textchanged event when the length exceeds and updates the UI(grid) which binds the observable collection of the above mentioned class. but the UI is not updating.
ObservableCollection<Item> lstItem = null;
private void textBox1_TextChanged(object sender, EventArgs e)
{
try
{
if (textBox1.Text.Length > 4)
{
Item obj = new Item();
obj.Name = textBox1.Text;
lstItem = new ObservableCollection<Item>();
dataGridView1.DataSource = lstItem;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message.ToString());
}
}
Thanks.
Look at this code:
Item obj = new Item();
obj.Name = textBox1.Text;
lstItem = new ObservableCollection<Item>();
dataGridView1.DataSource = lstItem;
You're setting the data source to an empty collection each time, and you're creating a new Item and then throwing it away again. Did you intend to add the item to the collection?
lstItem = new ObservableCollection<Item> { obj };
(It's not really clear whether you should be creating a new collection or even a new item - perhaps you should be using something like:
lstItem[0].Name = textBox1.Text;
instead?)
Related
I am trying to create Suggestion Searchbar using Entry
i was able to create the suggestion searchbar but i am not able to change the look of this Entry, i want to remove the tooltip above (Search by Speciality..) and just want it to look like other entry in the app
could anyone help me what and where i had to make change for getting that look
here is my code
Xamarin Android :
[assembly: ExportRenderer(typeof(AutoCompleteViewv2),
typeof(AutoCompleteViewRendererv2))]
namespace App.Droid.Renderers.RevisedRenderer
{
public class AutoCompleteViewRendererv2 :
FormsAppCompat.ViewRenderer<AutoCompleteViewv2, TextInputLayout>
{
public AutoCompleteViewRendererv2(Context context) : base(context)
{
}
private AppCompatAutoCompleteTextView NativeControl => Control?.EditText
as AppCompatAutoCompleteTextView;
protected override TextInputLayout CreateNativeControl()
{
var textInputLayout = new TextInputLayout(Context);
var autoComplete = new AppCompatAutoCompleteTextView(Context)
{
BackgroundTintList = ColorStateList.ValueOf(GetPlaceholderColor()),
Text = Element?.Text,
Hint = Element?.Placeholder,
};
GradientDrawable gd = new GradientDrawable();
gd.SetColor(global::Android.Graphics.Color.Transparent);
autoComplete.SetBackground(gd);
if (Element != null)
{
autoComplete.SetHintTextColor(Element.PlaceholderColor.ToAndroid());
autoComplete.SetTextColor(Element.TextColor.ToAndroid());
}
textInputLayout.AddView(autoComplete);
return textInputLayout;
}
protected override void OnElementChanged(ElementChangedEventArgs<AutoCompleteViewv2> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// unsubscribe
NativeControl.ItemClick -= AutoCompleteOnItemSelected;
var elm = e.OldElement;
elm.CollectionChanged -= ItemsSourceCollectionChanged;
}
if (e.NewElement != null)
{
SetNativeControl(CreateNativeControl());
// subscribe
SetItemsSource();
SetThreshold();
KillPassword();
NativeControl.TextChanged += (s, args) => Element.RaiseTextChanged(NativeControl.Text);
NativeControl.ItemClick += AutoCompleteOnItemSelected;
var elm = e.NewElement;
elm.CollectionChanged += ItemsSourceCollectionChanged;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Entry.IsPasswordProperty.PropertyName)
KillPassword();
if (e.PropertyName == AutoCompleteViewv2.ItemsSourceProperty.PropertyName)
SetItemsSource();
else if (e.PropertyName == AutoCompleteViewv2.ThresholdProperty.PropertyName)
SetThreshold();
}
private void AutoCompleteOnItemSelected(object sender, AdapterView.ItemClickEventArgs args)
{
var view = (AutoCompleteTextView)sender;
var selectedItemArgs = new SelectedItemChangedEventArgs(view.Text);
var element = (AutoCompleteViewv2)Element;
element.OnItemSelectedInternal(Element, selectedItemArgs);
}
private void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
var element = (AutoCompleteViewv2)Element;
ResetAdapter(element);
}
private void KillPassword()
{
if (Element.IsPassword)
throw new NotImplementedException("Cannot set IsPassword on a AutoComplete");
}
private void ResetAdapter(AutoCompleteViewv2 element)
{
var adapter = new BoxArrayAdapter(Context,
Android.Resource.Layout.SimpleDropDownItem1Line,
element.ItemsSource.ToList(),
element.SortingAlgorithm);
NativeControl.Adapter = adapter;
adapter.NotifyDataSetChanged();
}
private void SetItemsSource()
{
var element = (AutoCompleteViewv2)Element;
if (element.ItemsSource == null) return;
ResetAdapter(element);
}
private void SetThreshold()
{
var element = (AutoCompleteViewv2)Element;
NativeControl.Threshold = element.Threshold;
}
#region Section 2
protected AColor GetPlaceholderColor() => Element.PlaceholderColor.ToAndroid(Color.FromHex("#80000000"));
#endregion
}
internal class BoxArrayAdapter : ArrayAdapter
{
private readonly IList<string> _objects;
private readonly Func<string, ICollection<string>, ICollection<string>> _sortingAlgorithm;
public BoxArrayAdapter(
Context context,
int textViewResourceId,
List<string> objects,
Func<string, ICollection<string>, ICollection<string>> sortingAlgorithm) : base(context, textViewResourceId, objects)
{
_objects = objects;
_sortingAlgorithm = sortingAlgorithm;
}
public override Filter Filter
{
get
{
return new CustomFilter(_sortingAlgorithm) { Adapter = this, Originals = _objects };
}
}
}
internal class CustomFilter : Filter
{
private readonly Func<string, ICollection<string>, ICollection<string>> _sortingAlgorithm;
public CustomFilter(Func<string, ICollection<string>, ICollection<string>> sortingAlgorithm)
{
_sortingAlgorithm = sortingAlgorithm;
}
public BoxArrayAdapter Adapter { private get; set; }
public IList<string> Originals { get; set; }
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
var results = new FilterResults();
if (constraint == null || constraint.Length() == 0)
{
results.Values = new Java.Util.ArrayList(Originals.ToList());
results.Count = Originals.Count;
}
else
{
var values = new Java.Util.ArrayList();
var sorted = _sortingAlgorithm(constraint.ToString(), Originals).ToList();
for (var index = 0; index < sorted.Count; index++)
{
var item = sorted[index];
values.Add(item);
}
results.Values = values;
results.Count = sorted.Count;
}
return results;
}
protected override void PublishResults(ICharSequence constraint, FilterResults results)
{
if (results.Count == 0)
Adapter.NotifyDataSetInvalidated();
else
{
Adapter.Clear();
var vals = (Java.Util.ArrayList)results.Values;
foreach (var val in vals.ToArray())
{
Adapter.Add(val);
}
Adapter.NotifyDataSetChanged();
}
}
}
}
how can i get rid of that tooltip or placeholder and make the text in middle
I was stuck in this exception when starting using Xamarin forms with MVVM implementation
Method not found: 'Xamarin.Forms.BindableObjectExtensions.SetBinding'.
It failed at the line var mainNav = new MainPage ()
public static Page GetMainPage ()
{
RegisterTypes ();
var mainNav = new MainPage ();
return mainNav;
}
Here is my code, I have remove the unrelated codes to keep it simple. As you can see, it is very basic, and I knew I must get something very basic wrong, but just can't figure it out.
Thanks in advance....
View
public class MainPage :ContentPage
{
public MainPage ()
{
BindingContext = new MainPageViewModel ();
var nameEntry = new Entry ();
nameEntry.SetBinding (Entry.TextProperty, "Name");
Content = new StackLayout
{
Spacing = 12,
Padding = 20,
VerticalOptions = LayoutOptions.Start,
Children = { nameEntry }
};
}
}
ViewModel
public class MainPageViewModel:BaseViewModel
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
OnPropertyChanged();
}
}
}
I tried your exact code in a new project (Xamarin 3.9) and it worked fine (I only tested Android).
I omitted the RegisterTypes() from GetMainPage() and implemented the BaseViewModel as follows:
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Maybe you just need to update your Xamarin?
Noob question probably.
I am developing a mvm wp7 app where the map shows pushpins of salons. The database is retrieved from a link.
The problem i am struggling with is that the observable collection data is not being loaded from the App._ViewModel (where the json serializer parses the database and works fine). On debugging the app shows a plain map and thats all. On returning a string attribute from the database causes a break on that code. i tried messagebox as well to show the string, still crashes.
Heres the code:
mainviewmodel.cs
public class MainViewModel
{
public bool IsDataLoaded { get; private set; }
public ObservableCollection<SalonViewModel> SalonCollection { get; private set; }
public MainViewModel()
{
IsDataLoaded = false;
}
public ObservableCollection<SalonViewModel> LoadData()
{
SalonCollection = new ObservableCollection<SalonViewModel>();
var wednesday = new Uri("http://blehbleh.txt");
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(wednesday);
return SalonCollection;
}
public void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ObservableCollection<SalonViewModel>));
ObservableCollection<SalonViewModel> list = serializer.ReadObject(e.Result) as ObservableCollection<SalonViewModel>;
foreach (SalonViewModel b in list)
{
SalonCollection.Add(new SalonViewModel { sid=b.sid,sname=b.sname,sgeo_lat=b.sgeo_lat,sgeo_lon=b.sgeo_lon,
}
this.IsDataLoaded = true;
}
catch (Exception ex)
{
//throw ex;
MessageBox.Show(ex.Message);
}
}
The App.cs
public partial class App : Application
{
private static MainViewModel viewModel;
public static MainViewModel _viewModel
{
get
{
if (viewModel == null)
{
viewModel = new MainViewModel();
}
return viewModel;
}
}
void LoadData()
{
if (!_viewModel.IsDataLoaded)
{
_viewModel.LoadData();
}
}
etc
Heres the mappage.cs
private void salon_map_Loaded (object sender, RoutedEventArgs e)
{
foreach (SalonViewModel Salon in App._viewModel.LoadData)
{
MessageBox.Show(Salon.sname);
Pushpin p = new Pushpin();
p.Content = Salon.sname + System.Environment.NewLine + "Rate: ";
Layer.AddChild(p, new GeoCoordinate(Salon.sgeo_lon, Salon.sgeo_lat));
}
Map1.Children.Add(Layer);
}
In your MainViewModel LoadData function, OpenReadAsync() is an asynchronous function, and thus returning SalonCollection on the next line will return an empty ObservableCollection, since the callback function wc_OpenReadCompleted has not run yet.
Also, the reason the MessageBox.Show crashes is because you are attempting to call a UI function on a non-UI thread (solution to that here: Dispatcher.Invoke() on Windows Phone 7?)
Instead of returning the ObservableCollection and manually adding children to the map from that, try binding a MapItemsControl layer of the Map to the ObservableCollection of your view model. There's a decent example of doing that here: Binding Pushpins to Bing Maps in Windows Phone
When my view wants the value of LogoStation, it returns null because my program has not yet executed LoadStation_Completed.
I want my program waits that LoadStation_Completed is executed before continuing.
Thx
public class Infos
{
#region propriétés
private DataServiceCollection<SyndicObject> _infosStation;
public DataServiceCollection<SyndicObject> InfosStation
{
get
{
return _infosStation;
}
set
{
_infosStation = value;
}
}
#endregion
string nameStation;
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
private ImageSource _logoStation;
public ImageSource LogoStation
{
get
{
return _logoStation;
}
set
{
_logoStation = value;
NotifyPropertyChanged("LogoStation");
}
}
public Infos(string station)
{
nameStation = station;
getInfos();
}
public void getInfos()
{
SyndicationContext service = new SyndicationContext(new Uri("http://test/817bee9d-faf4-4680-9d05-e41c2c90ae5a/"));
IQueryable<SyndicObject> requete = (from objectSki in service.Objects
where objectSki.NOMSTATION == nameStation
select objectSki);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
InfosStation = new DataServiceCollection<SyndicObject>();
InfosStation.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(InfoStation_LoadCompleted);
InfosStation.LoadAsync(requete);
}
);
}
void InfoStation_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
LogoStation = new BitmapImage(new Uri(#"http://test/upload/" + InfosStation[0].LOGO, UriKind.Absolute));
}
}
By using the property setter you are using NotifyPropertyChanged (correctly) to tell the UI bound to LogoStation that it has been updated. This should mean that the UI will display nothing initially and then the image when the load has completed.
Without seeing your view code what you have here looks correct - apart from the fact that your Infos class doesn't inherit from INotifyPropertyChanged. This means that the event never gets sent.
Update your class definition and you should be good to go.
Does anyone have sample code on how to create a Region Adapter for AvalonDock's DocumentPane and DockingPane?
The Markus Raufer has added two region adapters to the CompositeWpfContrib project at CodePlex that supports both DocumentPane and DockingPane.
I have used Raffaeu Bermuda snippets to support Avalon tab region adapter, but found that there is some issues are not solved:
1- It does not support Activating a a certain view (aka - tab - DockableContent), so the code Region.Activate(object view) will not work.
2- All the Tabs are active by default in the region. So Region.ActiveViews collection by default has all the views, this is not ideal, as sometimes I needed to verify if a view is active or not (you could imagine a save button on a tool bar region that executes a SaveCommand only on the current active view = tab in our case)
3- Closed views doesn't actually get closed, only hidden. Even if you set the HideOnClose = true when adding the newDockableContent, it is still not removed from Region.Views collection. This could lead to memory leaks issues.
4- If you have a previously added DockableContent in the Pane, they will not get synchronized and added to the Region.Views collection.
So here are the code I am using now, it is just a small tweak from the Selector Adapter and Selector Sync Behavior found in PRISM source code:
AvalonRegionAdapter Class:
public class AvalonRegionAdapter : RegionAdapterBase<DocumentPane>
{
public AvalonRegionAdapter(IRegionBehaviorFactory factory) : base(factory) {}
protected override void AttachBehaviors(IRegion region, DocumentPane regionTarget)
{
if (region == null) throw new System.ArgumentNullException("region");
//Add the behavior that syncs the items source items with the rest of the items
region.Behaviors.Add(AvalonDocumentSyncBehavior.BehaviorKey,
new AvalonDocumentSyncBehavior()
{
HostControl = regionTarget
});
base.AttachBehaviors(region, regionTarget);
}
protected override void Adapt(IRegion region, DocumentPane regionTarget){ }
protected override IRegion CreateRegion()
{
return new Region();
}
}
AvalonDocumentSyncBehavior Behavior Code:
public class AvalonDocumentSyncBehavior : RegionBehavior, IHostAwareRegionBehavior
{
/// <summary>
/// Name that identifies the SelectorItemsSourceSyncBehavior behavior in a collection of RegionsBehaviors.
/// </summary>
public static readonly string BehaviorKey = "AvalonDocumentSyncBehavior";
private bool updatingActiveViewsInHostControlSelectionChanged;
private Selector hostControl;
/// <summary>
/// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
/// </summary>
/// <value>
/// A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
/// </value>
/// <remarks>For this behavior, the host control must always be a <see cref="Selector"/> or an inherited class.</remarks>
public DependencyObject HostControl
{
get
{
return this.hostControl;
}
set
{
this.hostControl = value as Selector;
}
}
/// <summary>
/// Starts to monitor the <see cref="IRegion"/> to keep it in synch with the items of the <see cref="HostControl"/>.
/// </summary>
protected override void OnAttach()
{
bool itemsSourceIsSet = this.hostControl.ItemsSource != null;
if (itemsSourceIsSet)
{
//throw new InvalidOperationException(Resources.ItemsControlHasItemsSourceException);
}
this.SynchronizeItems();
this.hostControl.SelectionChanged += this.HostControlSelectionChanged;
this.Region.ActiveViews.CollectionChanged += this.ActiveViews_CollectionChanged;
this.Region.Views.CollectionChanged += this.Views_CollectionChanged;
}
private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
int startIndex = e.NewStartingIndex;
foreach (object newItem in e.NewItems)
{
UIElement view = newItem as UIElement;
TabViewModel viewModel = ((UserControl)view).DataContext as TabViewModel;
if (view != null)
{
DockableContent newDockableContent = new DockableContent();
newDockableContent.Content = newItem;
//if associated view has metadata then apply it.
newDockableContent.Title = view.GetType().ToString();
if (viewModel != null)
{
//Image img = new Image();
//img.Source = new BitmapImage(new Uri(#"Resources/Alerts.png", UriKind.Relative));
newDockableContent.Title = viewModel.TabModel.Title;
newDockableContent.IsCloseable = viewModel.TabModel.CanClose;
//newContentPane.Icon = img.Source;
}
//When contentPane is closed remove from the associated region
newDockableContent.Closed += new EventHandler(newDockableContent_Closed);
newDockableContent.HideOnClose = false;
this.hostControl.Items.Add(newDockableContent);
newDockableContent.Activate();
}
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (object oldItem in e.OldItems)
{
this.hostControl.Items.Remove(oldItem);
}
}
}
void newDockableContent_Closed(object sender, EventArgs e)
{
var dockableContent = sender as DockableContent;
if(dockableContent != null)
if (this.Region.Views.Contains(dockableContent.Content))
{
this.Region.Remove(dockableContent.Content);
}
}
private void SynchronizeItems()
{
List<object> existingItems = new List<object>();
// Control must be empty before "Binding" to a region
foreach (object childItem in this.hostControl.Items)
{
existingItems.Add(childItem);
}
foreach (object view in this.Region.Views)
{
this.hostControl.Items.Add(view);
}
foreach (object existingItem in existingItems)
{
this.Region.Add(existingItem);
}
}
private void ActiveViews_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (this.updatingActiveViewsInHostControlSelectionChanged)
{
// If we are updating the ActiveViews collection in the HostControlSelectionChanged, that
// means the user has set the SelectedItem or SelectedItems himself and we don't need to do that here now
return;
}
if (e.Action == NotifyCollectionChangedAction.Add)
{
var selectedDockableContent = this.hostControl.SelectedItem as DockableContent;
if (selectedDockableContent != null
&& selectedDockableContent.Content != null
&& selectedDockableContent.Content != e.NewItems[0]
&& this.Region.ActiveViews.Contains(selectedDockableContent.Content))
{
this.Region.Deactivate(selectedDockableContent.Content);
}
var _UIElement = e.NewItems[0] as FrameworkElement;
this.hostControl.SelectedItem = _UIElement.Parent;
}
else if (e.Action == NotifyCollectionChangedAction.Remove &&
e.OldItems.Contains(this.hostControl.SelectedItem))
{
this.hostControl.SelectedItem = null;
}
}
private void HostControlSelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
// Record the fact that we are now updating active views in the HostControlSelectionChanged method.
// This is needed to prevent the ActiveViews_CollectionChanged() method from firing.
this.updatingActiveViewsInHostControlSelectionChanged = true;
object source;
source = e.OriginalSource;
if (source == sender)
{
foreach (object item in e.RemovedItems)
{
// check if the view is in both Views and ActiveViews collections (there may be out of sync)
var dockableContent = item as DockableContent;
if (this.Region.Views.Contains(dockableContent.Content) && this.Region.ActiveViews.Contains(dockableContent.Content))
{
this.Region.Deactivate(dockableContent.Content);
}
}
foreach (object item in e.AddedItems)
{
var dockableContent = item as DockableContent;
if (this.Region.Views.Contains(dockableContent.Content) &&
!this.Region.ActiveViews.Contains(dockableContent.Content))
{
this.Region.Activate(dockableContent.Content);
}
}
}
}
finally
{
this.updatingActiveViewsInHostControlSelectionChanged = false;
}
}
}
Code on bootstrapper to configure the Adapter
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
var mappings = base.ConfigureRegionAdapterMappings();
mappings.RegisterMapping(typeof(AvalonDock.DocumentPane),
this.Container.Resolve<AvalonRegionAdapter>());
return mappings;
}
Then you need the TabModel and the TabViewModel as fromRaffaeu Bermuda
public sealed class TabModel : DependencyObject
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
// Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(TabModel));
public bool CanClose
{
get { return (bool)GetValue(CanCloseProperty); }
set { SetValue(CanCloseProperty, value); }
}
// Using a DependencyProperty as the backing store for CanClose. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CanCloseProperty =
DependencyProperty.Register("CanClose", typeof(bool), typeof(TabModel));
public bool IsModified
{
get { return (bool)GetValue(IsModifiedProperty); }
set { SetValue(IsModifiedProperty, value); }
}
// Using a DependencyProperty as the backing store for IsModified. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsModifiedProperty =
DependencyProperty.Register("IsModified", typeof(bool), typeof(TabModel));
}
And a TabViewModel acting as a base class:
public class TabViewModel : INotifyPropertyChanged
{
private TabModel _tabModel;
public TabModel TabModel
{
get { return this._tabModel; }
set
{
this._tabModel = value;
OnPropertyChanged("TabModel");
}
}
public TabViewModel()
{
this.TabModel = new TabModel();
this.TabModel.CanClose = true;
this.TabModel.IsModified = false;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
Let me know if you need further help, I will post a blog this in the near future.
Since the Avalon DocumentPane and DockingPane are both based on the System.Windows.Controls.Primitives.Selector you can use the default SelectorRegionAdapter in Prism.
Just base your control on DockableContent
<ad:DockableContent x:Class="DesignerWPF.UserControl1"
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:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
d:DesignHeight="300" d:DesignWidth="300" Title="dans">
<Grid>
<TextBox Text="sdfdf"></TextBox>
</Grid>
</ad:DockableContent>
on your main Shell.xmal set the regions in the dockablepane
<ad:DockingManager x:Name="dockManager" Grid.Row="1" Margin="0,4,0,0">
<ad:ResizingPanel Orientation="Horizontal">
<ad:DockablePane cal:RegionManager.RegionName="LeftRegion">
</ad:DockablePane>
<ad:DocumentPane cal:RegionManager.RegionName="DocumentRegion">
</ad:DocumentPane>
</ad:ResizingPanel>
</ad:DockingManager>
then when you initialize your presenter for your control it will get displayed in the dock.
public class UserTestControl : IModule
{
public UserTestControl(IUnityContainer container, IRegionManager regionManager)
{
Container = container;
RegionManager = regionManager;
}
public void Initialize()
{
var addFundView = Container.Resolve<UserControl1>();
RegionManager.Regions["LeftRegion"].Add(addFundView);
}
public IUnityContainer Container { get; private set; }
public IRegionManager RegionManager { get; private set; }
}
My advice would be to look in Microsoft.Practices.Composite.Presentation.Regions in the Prism source. Specifically, take a look at the ItemsControlRegionAdapter and use it as a template. Remember to inherit from RegionAdapterBase<>:
public class ItemsControlRegionAdapter : RegionAdapterBase<ItemsControl>
and to override ConfigureRegionAdapterMappings() in the bootstrapper. That would look something like:
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
mappings.RegisterMapping(typeof(Canvas), Container.Resolve<CanvasRegionAdapter>());
return mappings;
}