ComboBox Whith a TreeView - wpf

I need to create a userControl like a Combobox.
In the items in need a TreeView and a Button.
If I navigate the Tree the Item should go to the Text Box in the Bottom.
If I click the Button the Tree should Collapsed.
My First idea was like This but it isn't good.
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Adresse, Mode=TwoWay}" MaxLength="50" MinWidth="170" Grid.Row="5" Margin="5,2,5,2"/>
<Button Width="25" Margin="2" Click="Down">
<Image Source="/C1_net;component/Images/arrow.jpg" HorizontalAlignment="Left" />
</Button>
</StackPanel>
<StackPanel x:Name="Tree" Orientation="Vertical" Visibility="Collapsed">
<sdk:TreeView Height="200" Name="treeView1" Width="200" />
<Button Content="{Binding Path=ApplicationStrings.OKButton, Source={StaticResource ResourceWrapper}}" Width="75" Margin="5" Click="OnOk" HorizontalAlignment="Right"/>
</StackPanel>
</StackPanel>
</Grid>
If I switch to Visible the Control needs more space.
So I need to bring the Tree in Front of the Rest of the Window.
Any ideas?

Ok.
I think you should revisit your interaction.
my problemm wase to think if i select i Item, The Tree wood be closed.
I will navigate in a Hirarchical DataObjekt and Put the Path as selectet Item.
So now I will to somting like this:
public interface ITreeViewItemModel
{
string SelectedValuePath { get; }
bool IsExpanded { get; set; }
bool IsSelected { get; set; }
IEnumerable<ITreeViewItemModel> GetHierarchy();
IEnumerable<string> GetDisplayHierarchy();
IEnumerable<ITreeViewItemModel> GetChildren();
}
and.
public class ComboBoxTreeView : ComboBox
{
private ExtendedTreeView _treeView;
private ContentPresenter _contentPresenter;
public ComboBoxTreeView()
{
this.DefaultStyleKey = typeof(ComboBoxTreeView);
}
......
I found This http://vortexwolf.wordpress.com/2011/04/29/silverlight-combobox-with-treeview-inside/

Related

How to access name tags in avalon dock data template

I have used media element in another app to play videos with the same implementation and it works as expected but whenever I put my control in my Avalon dock data template I get this error message "The name'VideoControl' does not exist in the current context on VideoControl.Play() even in this same app it I put my controls outside the Avalon dock tags it works as expected.
<DockPanel Name="df" Grid.Row="2" FlowDirection="LeftToRight" LastChildFill="True" SnapsToDevicePixels="True" WindowChrome.ResizeGripDirection="TopLeft">
<avalonDock:DockingManager x:Name="dockManager" AnchorablesSource="{Binding Tools}" DocumentsSource="{Binding Files}" ActiveContent="{Binding ActiveDocument, Mode=TwoWay, Converter={StaticResource ActiveDocumentConverter}}" DockPanel.Dock="Left" Grid.Row="2" BorderBrush="Black" BorderThickness="1">
<avalonDock:DockingManager.LayoutItemTemplateSelector>
<localController:PanesTemplateSelector>
<localController:PanesTemplateSelector.PreviewViewTemplate>
<DataTemplate>
<StackPanel>
<MediaElement Canvas.Left="20" Canvas.Top ="40" x:Name= "VideoControl" LoadedBehavior="Manual" UnloadedBehavior="Stop" ></MediaElement>
<Button Height="23" HorizontalAlignment="Left" Margin="15,0,0,13" Name="PlayButton" VerticalAlignment="Bottom" Width="75" Click="PlayClick">Play</Button>
<Button Height="23" HorizontalAlignment="Left" Margin="103,0,0,13" Name="PauseButton" VerticalAlignment="Bottom" Width="75" Click="PauseClick">Pause</Button>
<Button Height="23" Margin="191,0,186,13" Name="StopButton" VerticalAlignment="Bottom" Click="StopClick">Stop</Button>
</StackPanel>
</DataTemplate>
</localController:PanesTemplateSelector.PreviewViewTemplate>
</localController:PanesTemplateSelector>
</avalonDock:DockingManager.LayoutItemTemplateSelector>
</avalonDock:DockingManager>
</DockPanel>
C# Class:
public class PanesTemplateSelector : DataTemplateSelector
{
public DataTemplate PreviewViewTemplate
{
get;
set;
}
#endregion
#region Template Selection
public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
{
//Creates a new collection of layout content
var itemAsLayoutContent = item as LayoutContent;
if (item is PreviewViewModel)
return PreviewViewTemplate;
//Returns selected template
return base.SelectTemplate(item, container);
}
#endregion
}
Isn't that an expected behavior? Accessing a control inside datatemplate by name is tricky. Use
ParentControl.FindName("VideoControl") as MediaElement
to retrieve your control

How to bind each button's image source from ListView to individual item from observable collection?

I have a Listview of Buttons like this:
<ListView ItemsSource="{Binding TestList}">
<ListViewItem >
<ListView.ItemTemplate>
<DataTemplate>
<Button Name="test" Grid.Row="0" Grid.Column="10" Grid.ColumnSpan="4" Grid.RowSpan="4" VerticalAlignment="Center" Background="Transparent">
<Button.Template>
<ControlTemplate>
<Grid>
<Image Source="?????????????????????????????????????????????"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</ListView.ItemTemplate>
And the code behind like this:
public class CodeBehind
{
private ObservableCollection<string> testList;
public ObservableCollection<string> TestList
{
get { return testList; }
set
{
testList = value;
}
}
public CodeBehind()
{
dummyModelList = new ObservableCollection<string>() { "/Assets/Image1", "/Assets/Image2", "/Assets/Image3"};
}
}
How to bind each button's image source to individual item from observable collection? I want to do this only in XAML.
What you are looking for is ItemTemplate (Gets or sets the DataTemplate used to display each item.) instead of buttons' template itself.
You use the ItemTemplate to specify the visualization of the data objects. If your ItemsControl is bound to a collection object and you do not provide specific display instructions using a DataTemplate, the resulting UI of each item is a string representation of each object in the underlying collection.
So when you set the ItemTemplate to an instance of DataTemplate, the DataTemplate will be used to render the items. The DataContext of the DataTemplate will be implicitly set to individual items in the bound collection, so you can bind the Image.Source to the DataContext itself using {Binding .} or {Binding}
<ListView ItemsSource="{Binding TestList}">
<ListView.ItemTemplate>
<DataTemplate>
<Button Name="test" Grid.Row="0" Grid.Column="10" Grid.ColumnSpan="4" Grid.RowSpan="4" VerticalAlignment="Center" Background="Transparent">
<Image Source="{Binding .}" />
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You should create a DataTemplate to show any controls in your ItemTemplate of ListView:
<ListView Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto*"/>
<RowDefinition Height="Auto*"/>
</Grid.RowDefinitions>
<Button>
<Image Source="{Binding AddressImage}" Width="20" Grid.Row="0" />
</Button>
<TextBlock Grid.Row="1" TextAlignment="Left" FontWeight="Light"
VerticalAlignment="Center" Text="{Binding UserName}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
Model:
public class Person
{
public int IdUser {get; set;}
public string UserName {get; set;}
public string AddressImage {get; set;}
}
code-behind:
public MainWindow()
{
PopulateCollection();
}
private void PopulateCollection()
{
ObservableCollection<Person> personColl = new ObservableCollection<Person>();
for (int i = 0; i <= 10; i++)
{
//here you can set any image what you want
personColl.Add(new Person() { IdUser=i, UserName="I am " + i.ToString(),
AddressImage="Assets/1.png"});
//Assets is a folder with images
}
listView.ItemsSource=personColl;
}

How to put an Expander inside Datatemplate?

Strange one.
I have a contentcontrol on a WPF form, this loads a datatemplate within it.
This shows up fine (handwritten summary code so ignore errors/lack of attributes):
<DataTemplate>
<Label Content="Found datatemplate" />
</DataTemplate>
This however renders blank
<DataTemplate>
<Expander Header="Why dont I show">
<Label Content="Found datatemplate" />
</Expander>
</DataTemplate>
I have set the expander to visibile, isexpanded to true etc and no matter what it doesn't render at all.
Confused- is this just not possible?
I've recently done something similar to what you're describing and it worked for me. I have an ItemsControl that binds to a collection of view models, each of which contains a UserControl representing custom content. I implemented the ItemsControl.ItemTemplate to display the custom control inside an Expander like this:
<ItemsControl Margin="0,20,0,0" ItemsSource="{Binding ControlItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="0,0,0,0"
BorderBrush="#E7E7E7"
BorderThickness="0,1,0,0"
Padding="20,0">
<Expander Foreground="#E7E7E7"
IsExpanded="{Binding Path=IsExpanded,
Mode=TwoWay}">
<Expander.Header>
<Grid>
<TextBlock HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="24"
Text="{Binding Title}" />
</Grid>
</Expander.Header>
<DockPanel>
<ScrollViewer MinHeight="250">
<ContentControl Content="{Binding Control}" />
</ScrollViewer>
</DockPanel>
</Expander>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This is what my view model looks like:
public class SidePanelControlItem : ModelBase
{
private bool _isExpanded;
public SidePanelControlItem(UserControl control)
{
if (control == null) { throw new ArgumentNullException("control");}
Control = control;
}
public string Title { get; set; }
public UserControl Control { get; private set; }
public bool IsExpanded
{
get { return _isExpanded; }
set
{
_isExpanded = value;
OnPropertyChanged("IsExpanded");
}
}
}

Reusable usercontrol with radiobuttons are being unchecked unexpectedly

I'm having an issue with the RadioButton when using a reusable UserControl. For some reason I am unable to check a radio button of each 'Chooser' control but instead when one radio button is checked, all other radio buttons in the current chooser and in the other choosers are unchecked. Does anyone know how to change this code so that I can have a checked item in each 'chooser' user control. The user control must be able to be dynamically built using a collection. In a real world example, each 'chooser' usercontrol will have different text values.
MainPage.xaml
<StackPanel x:Name="LayoutRoot" Background="White">
<radioButtonTest:Chooser />
<radioButtonTest:Chooser />
<radioButtonTest:Chooser />
</StackPanel>
Chooser.xaml
<UserControl x:Class="RadioButtonTest.Chooser"
xmlns ...>
<StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
<TextBlock x:Name="MyLabel" Text="Choices:" VerticalAlignment="Center" Margin="0,0,10,0" />
<ItemsControl x:Name="MyChooser" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Height="22" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="{Binding}" MinWidth="35" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</UserControl>
Chooser.xaml.cs
public partial class Chooser
{
public Chooser()
{
InitializeComponent();
// adding some test items to the itemscontrol
MyChooser.ItemsSource = new ObservableCollection<string>
{
"first",
"second",
"third"
};
}
}
Turns out I needed to use the GroupName property of the RadioButton to dictate the groupings. I did this by changing the item source to a custom class with a Group property of type string and binding this property to the GroupName property on the RadioButton.
XAML:
<DataTemplate>
<RadioButton ... Content="{Binding Name}" GroupName="{Binding Group}" />
</DataTemplate>
C#:
public Chooser()
{
InitializeComponent();
// the groupName needs to be the same for each item
// in the radio group, but unique for each separate group.
var groupName = Guid.NewGuid().ToString();
MyChooser.ItemsSource = new ObservableCollection<RadioButtonGroupItem>
{
new RadioButtonGroupItem {Group = groupName, Name = "first"},
new RadioButtonGroupItem {Group = groupName, Name = "second"},
new RadioButtonGroupItem {Group = groupName, Name = "third"}
};
}
public class RadioButtonGroupItem
{
public string Name { get; set; }
public string Group { get; set; }
}
Hope this helps someone.

Failing to Add UserControl To Existing Grid on SelectedItem in ListBox

I am new into WPF. I am currently developing an application where my solution in MSVC# 2010 has 2 projects. One project(i.e.MSPBoardControl) has a mainwindow.xaml and I have added another wpf window ConnectView.xaml. By using the grid in mainwindow.xaml I am able to add the Connectview.xaml view to my application in mainwindow.xaml.cs. My 2nd project is a classlibrary which has a usercontrol(i.e. Voltage).
Mainwindow.xaml: This grid is the one to which I add my Connectview.xaml UI component
<Grid Grid.Row="0" Name="MainGrid" HorizontalAlignment="Stretch" Style="{DynamicResource styleBackground}" >
</Grid>
I have a listbox in my mainwindow.xaml towards the left side which has list of items(i.e. Voltage, Clock etc). The right side of .xaml has my grid which is shown above(contains the connectview on startup). What I basically need is when I click the item from the listbox, I want to hide the view which is shown on startup(connectview) and make the selecteditem UI component visible.
As mentioned in the beginning I want to make a usercontrol of my classlibrary(VoltageView) visible on clicing "Voltage" item from Listbox.
ListBox in my mainwindow.xaml:
<ListBox Name="ButtonPanel" Style="{DynamicResource styleBanner}" ItemsSource="{Binding BoardOperations, Mode=TwoWay}" SelectedItem="{Binding SelectedList}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Name="BoardTabChanger" Margin="53,27,0,0" Text="{Binding ListName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The ViewModel Class of MSPBoardControl is here:
public class BoardControlViewModel : INotifyPropertyChanged
{
public ObservableCollection<BoardControlModel> m_BoardOperation;
public List<ConnectModel> m_BoardNames;
public BoardControlViewModel()
{
//Adding items to ListBox
}
public List<ConnectModel> BoardNames
{
get; set;
}
private ConnectModel m_SelectedBoardItem;
public ConnectModel SelectedBoard
{
get; set;
}
public ObservableCollection<BoardControlModel> BoardOperations
{
get; set;
}
//GIVES ME THE SELECTED ITEM FROM LISTBOX
private BoardControlModel m_SelectedListItem;
public BoardControlModel SelectedList
{
get
{
return m_SelectedListItem;
}
set
{
m_SelectedListItem = value;
onListSelected(value);
NotifyPropertyChanged("SelectedList");
}
}
private void onListSelected(BoardControlModel SelectedItem)
{
if (SelectedItem.ListName == "Voltage")
{
//HOW CAN I ADD THE VOLTAGEVIEW HERE???
}
}
The above method OnListSelected() retrieves the selecteditem and when I check the condition dat item = voltage, I want to add the voltageview component to my maingrid and hide the connectview.
VoltageView.xaml:
<Grid Name="VoltageControl" Style="{DynamicResource styleBackground}" DataContext="{StaticResource VoltageViewModel}" >
<Label Content="Label" FontSize="15" Foreground="Black" Height="28" HorizontalAlignment="Left" Margin="10,31,0,0" Name="label9" VerticalAlignment="Top" Width="117" />
<Label Content="Set Voltage" FontSize="15" Foreground="Black" Height="28" HorizontalAlignment="Left" Margin="150,31,0,0" Name="label10" VerticalAlignment="Top" Width="117" />
<Label Content="Current Value" FontSize="16" Foreground="Black" Height="28" HorizontalAlignment="Left" Margin="300,31,0,0" Name="label11" VerticalAlignment="Top" Width="117" />
<Label Content="Enable/Disable" FontSize="15" Foreground="Black" Height="28" HorizontalAlignment="Left" Margin="460,31,0,0" Name="label12" VerticalAlignment="Top" Width="127" />
<Button Content="Refresh All" FontSize="13" Height="25" HorizontalAlignment="Left" Margin="230,520,0,0" Name="RefreshBtn" VerticalAlignment="Top" Width="105" />
</Grid>
Please help!!!
I'm going to keep this general(ish). Your best bet is probably to add a property on BoardControlViewModel of type Grid (or whatever UIElement that is common to voltage and connect). As the selection changes, change the UI property to the view you want and hit NotifyPropertyChanged for that property. You can call NotifyPropertyChanged right from onListSelected if you like. Bind the content of whatever grid you're using to this property, prefferably right in the xaml. When the property changes, WPF will notify the grid that its bound content has changed and it will query your new property to see what it should be.

Resources