|
Are you only going one way? UI -> VM? If so, there is a SelectedItem bindable property on the TreeView that you can use.
If you want two-way binding (set the selection from the VM), that is a lot more work.
|
|
|
|
|
It is binding from UI to VM. I just need to get the value of the selecteditem, and the SelectedItem of the TreeView is Read Only. So how do I get the Value of the Selected Item? Thanks in advance.
|
|
|
|
|
So what is the issue? SelectedItem contains your selected item. It is only read only to you. The TreeView control sets internally. You do need to use one way binding though.
|
|
|
|
|
This guy [^]has some excellent treeview article which may help you.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Why can't you just bind SelectedItem from the TreeView to your VM ?
<TreeView SelectedItem="{Binding SelectedItem, mode=TwoWay}">
<TreeViewItem Header="Category" ItemsSource="{Binding Categories}" />
<TreeViewItem Header="Colors" ItemsSource="{Binding Colors}" />
</TreeView>
|
|
|
|
|
The +/- is a styled ToggleButton (ControlTemplate\Grid\ToggleButton).
The content is a normal styled ContentPresenter(s) hosted in an ItemsPresenter (ControlTemplate\Grid\ItemsPresenter). An ItemsPresenter is a collection of Items. For the TreeView, these are additional ItemsPresenter(s) to do the hierarchy.
If I was going to do what you want to do, I'd remove the ToggleButton from the TreeViewItem style (to hide it) and place it in the item template (item template is != item style). You'll notice the trigger for HasItems sets the visibility to HIDDEN if it doesn't have items vs. COLLAPSED so the tree doesn't get misaligned.
From the ItemTemplate you'd use the same bindings pretty much. Except the DataTemplate would be something like
<DataTemplate>
<Grid>
<Button ... HorizontalAlignment="Left" VerticalAlignment="Top" />
<ToggleButton ... HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</DataTemplate>
Just an FYI, this will give you what you want visually, but not from a usability stand point (maybe). You won't be able to click on the button in the upper left corner where the +/- is.
|
|
|
|
|
You don't lose any functionality by putting stuff in the DataTemplate. What I said earlier about the "bindings are mostly the same" was slightly misleading... they are, but you need to repoint the functionality ones (like the ToggleButton) to the TreeViewItem (relative source / find ancestor TreeViewItem) and not your data item. Remember, there is *always* a TreeViewItem. If you give the ItemsSource a TreeViewItem, WPF will use that instance of it, otherwise, it'll wrap your object in an implied one it creates.
|
|
|
|
|
As my other reply said, you don't recreate all this functionality. There is a wrapper TreeViewItem always created for you whether you like it or not . Well, there is a way to override that, but that's beyond the scope of this thread.
|
|
|
|
|
Hello,
My WPF application (WpfApplication1) is, for its XAML part, composed of an single empty grid.
Elements are loaded inside this grid from an external XAML file, read through XamlReader.
This external Xaml file contains (for the purpose of this example) a URL to an image which should be located in the 'My documents' user folder.
The problem is that during importation the url from images should be relative to the application which is loading the file!
In other words, this URL should be relative to the application (pack://siteoforigin:, pack://application)
...and in my case, this path is 'outside' from that context and should be built this way:
Environment.GetFolderPath(Environment.SpecialFolde r.MyDocuments) & "Theme\"
So, I wrote a Converter, hoping to build the complete path url...but without succes!!
> 'Impossible to create the unknow type '{clr-namespace:WpfApplication1}imgurlConvert'.'
The application XAML part:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:test"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="MainWindow" Title="main" Height="600" Width="800">
<Grid></Grid>
</Window>
The application VB part:
Imports System.IO
Class MainWindow
Public Shared ThemeTempFolder As String = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\Theme\"
Public Shared themeGrid As Grid
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Debug.Print(ThemeTempFolder)
loadInterface()
End Sub
Sub loadInterface()
Dim GridUri As String = ThemeTempFolder & "theme.xaml"
Dim fs As FileStream = New FileStream(GridUri, FileMode.Open, FileAccess.Read)
Dim sri = TryCast(System.Windows.Markup.XamlReader.Load(fs), Grid)
Me.Content = sri
fs.Close()
themeGrid = LogicalTreeHelper.FindLogicalNode(sri, "themeGrid")
End Sub
End Class
Public Class imgurlConvert
Implements IValueConverter
Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
Dim valConv As String = MainWindow.ThemeTempFolder & value
If File.Exists(valConv) Then
Return valConv
End If
Return Nothing
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
Return value
End Function
End Class
The XAML file to load:
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:WpfApplication1" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib" Name="themeGrid">
<Grid.Resources>
<local:imgurlConvert x:Key="urlConvert" />
</Grid.Resources>
<Grid Name="mainGrid">
<Image Source={Binding Path="image.png", Converter={StaticResource urlConvert}} CacheOption="OnLoad" x:Name="Image1"/>
</Grid>
</Grid>
I hope that I was clear enough!? Thanks for helping me!!
|
|
|
|
|
How can we integrate HTML Help files with Table Of Contents into an application developing in C#.NET.
While installing the application (.exe), the help files also should get extracted into the installation folder and when the user press F1 key or click on the Help Icon/ link, the index.htm page should display in a browser.
Please note that the html files are having CSS, Images, and Scripts in separate folders.
Kind regards, Adarsh
|
|
|
|
|
I use InnoSetup for my installation program; it can create folders with their contents.
Add a WebBrowser control to your application to display HTML help. The WebBrowser control has methods for navigating to the content you want to display.
|
|
|
|
|
I'm not sure why (probably a bug in .NET), but this only works when you remove the default template. I.e.:
<ContentControl.ContentTemplate>
<DataTemplate>
<TextBlock Text="REPLACE ME WITH THE CORRECT TEMPLATE"></TextBlock>
</DataTemplate>
</ContentControl.ContentTemplate>
Remove that portion and the triggers will work. I also tried adding a button to switch the type at runtime and it worked fine.
modified 3-Apr-14 19:20pm.
|
|
|
|
|
I'm really stuck here. I MUST get this working. I have been asking questions about this but I can't seem to get an answer that makes sense to me.
Either I'm not asking the question right, or I don't understand the answers.
See this image[^].
This should be simple. I just don't get it. I can't find a single example if a UserControl with a ViewModel that gets data from the host its on.
I have a sample control that I wrote but won't work here[^].
Can someone point me to an example of how this is done?
Many Thanks!
If it's not broken, fix it until it is
|
|
|
|
|
OK, there's a couple of problems with your sample code which aren't helping:
- In
LookupComboControlViewModel , the People property passes the wrong property name to the RaisePropertyChanged method; - Your category IDs start at zero, which happens to be the default value of the
_CategoryId field, so when you select the "Presidents" category, the people won't be loaded;
There might be a more elegant way to make this work, but for a quick hack you can use a property changed callback on your DependencyProperty to manually change the property on your DataContext :
public CategoryModel SelectedCategory
{
get { return (CategoryModel)GetValue(SelectecCategoryProperty); }
set { SetValue(SelectecCategoryProperty, value); }
}
public static readonly DependencyProperty SelectedCategoryProperty = DependencyProperty.Register(
"SelectedCategory", typeof(CategoryModel), typeof(LookupComboControl),
new UIPropertyMetadata(null, SelectedCategoryChanged));
private static void SelectedCategoryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var view = (LookupComboControl)d;
var viewModel = (LookupComboControlViewModel)view.DataContext;
var model = (CategoryModel)e.NewValue;
viewModel.CategoryId = (model == null) ? 0 : model.Id;
}
I've updated your sample: http://1drv.ms/1j69N0P[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you! Thank you! Thank you!
I had tried to get the dc in the callback before, but I couldn't make it work.
The universe is in alignment again!!
If it's not broken, fix it until it is
|
|
|
|
|
How Should I customize Ribbon control Menu in my WPF application?
|
|
|
|
|
|
Hi,
I have a textbox and which is having validation on its data. I am showing data error as a tooltip. But tooltip is not visible fully.how do i wrap it or increase its width?
<Style x:Key="ValidationTextBoxStyle" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Validation.ErrorTemplate"
Value="{StaticResource ErrorTemplate}" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip">
<Setter.Value>
<Binding Path="(Validation.Errors)[0].ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="#FF666666"/>
</Trigger>
</Style.Triggers>
</Style>
<TextBox x:Name="FileObjectName" Grid.Column="1" VerticalContentAlignment="Center" Height="Auto" MaxLines="1"
Style="{StaticResource ValidationTextBoxStyle}" IsEnabled="{Binding IsNameEditable}">
<TextBox.Text>
<Binding Path="Name" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" ValidatesOnExceptions="True">
<Binding.ValidationRules>
<validation:LibraryObjectFileNameValidationRule
ValidatesOnTargetUpdated="True"
PropertyName="{x:Static resources:CommonStorageUIContent.FileNamePropertyName}" />
<validation:PropertyLengthValidationRule
ValidatesOnTargetUpdated="True"
IsAlphaNumericValuesOnly="True"
MaxPropertyLength="{x:Static validation:Constants.KeyPropertyMaxLengthDefaultValue}"
PropertyName="{x:Static resources:CommonStorageUIContent.FileNamePropertyName}"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
|
|
|
|
|
I have this style:
<Style TargetType="telerik:GridViewRow">
<Setter Property="IsSelected" Value="{Binding IsExpanded, RelativeSource={RelativeSource Self}}" />
</Style>
It expands the row when it's selected. Instead of this, I need to bind the grid row's IsExpanded to a property called IsRowExpanded on the row's data object. The IsRowExpand will be set to true on the back end if there are any child rows.
Can someone show me how to do this binding?
<Style TargetType="telerik:GridViewRow">
<Setter Property="IsExpanded" Value="[WHAT GOES HERE?]" />
</Style>
Many thanks
If it's not broken, fix it until it is
|
|
|
|
|
This is a bit long, and I'm not entirely sure how to word my question...
I am developing a prototype for a simple lookup control[^].
The source is here[^].
The Category combo is on the window, and below it is my control. When a category is selected, I want the Lookup control to get the category Id:
<ComboBox x:Name="CategoryCombo"
Grid.Row="1"
ItemsSource="{Binding Categories}"
SelectedValuePath="Id"
DisplayMemberPath="Category"
VerticalAlignment="Center"
Height="24"
Width="375"/>
<views:LookupComboControl Grid.Row="2"
CategoryId="{Binding ElementName=CategoryCombo, Path=SelectedValue, Mode=TwoWay}"
Height="70"
Width="400"/>
My Lookup control's VM is pretty simple:
public class LookupComboControlViewModel : _ModelBase
{
private List<PersonModel> _People = new List<PersonModel>();
public List<PersonModel> People
{
get { return _People; }
set
{
if (_People != value)
{
_People = value;
RaisePropertyChanged("ComboSourceData");
}
}
}
private string _CategoryName;
public string CategoryName
{
get { return _CategoryName; }
set
{
if (_CategoryName != value)
{
_CategoryName = value;
RaisePropertyChanged("CategoryName");
}
}
}
private int _CategoryId;
public int CategoryId
{
get { return _CategoryId; }
set
{
if (_CategoryId != value)
{
_CategoryId = value;
RaisePropertyChanged("CategoryId");
loadData();
}
}
}
private void loadData()
{
DAL dal = new DAL();
People = dal.GetPeopleForCategory(CategoryId);
}
}
When a category is selected, I want to set the lookup control's CateogoryId. The lookup control has this DP in it.
public LookupComboControl()
{
InitializeComponent();
this.DataContext = new LookupComboControlViewModel();
}
public int CategoryId
{
get { return (int)GetValue(CategoryIdProperty); }
set { SetValue(CategoryIdProperty, value); }
}
public static readonly DependencyProperty CategoryIdProperty =
DependencyProperty.Register("CategoryId", typeof(int), typeof(LookupComboControl));
The ultimate goal is to have the VM for the Lookup control know when the CategoryId was set. When I select a cateogory, nothing happens. What am I doing wrong here?
Thanks
If it's not broken, fix it until it is
modified 25-Mar-14 14:16pm.
|
|
|
|
|
Don't you need to bind the SelectedItem property in the Combo to something so you know what is selected?
|
|
|
|
|
I could be wrong, but I don't think so. The user control is bound to the Category combo's SelectedValue, so when a category is selected, it's value (CategoryId), should be passed to my control.
views:LookupComboControl Grid.Row="2"
CategoryId="{Binding ElementName=CategoryCombo, Path=SelectedValue, Mode=TwoWay}"
Height="70"
Width="400"/>
If it's not broken, fix it until it is
|
|
|
|
|
I think you are right in principal, but in practice I'm sure I've seen/had problems with selected value not working as expected...
For the sake of a test, change it to bind to the text property and see if it starts working- at least that narrows the issue down!
|
|
|
|
|
OK, I think you were right. The Output window was showing a Null being passed as SelectedValue.
So I made the following changes::
In the control:
public object SelectecCategory
{
get { return (object)GetValue(SelectecCategoryProperty); }
set
{
SetValue(SelectecCategoryProperty, value);
}
}
public static readonly DependencyProperty SelectecCategoryProperty =
DependencyProperty.Register("SelectecCategory", typeof(object), typeof(LookupComboControl));
In the MainWindow
<ComboBox x:Name="CategoryCombo"
Grid.Row="1"
ItemsSource="{Binding Categories}"
SelectedValuePath="Id"
DisplayMemberPath="Category"
VerticalAlignment="Center"
Height="24"
Width="375"/>
<views:LookupComboControl Grid.Row="2"
SelectecCategory="{Binding ElementName=CategoryCombo, Path=SelectedItem, Mode=TwoWay}"
Height="70"
Width="400"/>
Now I get no binding errors. But the original problem still exists... Nothing happens.
So here's my question - The UserControl has the DP. Once the MainWindow sets the DP, how does the User Control's VM know about it? Again, I need to somehow get the selected category into the ViewModel.
[UPDATE]
The source is https://onedrive.live.com/redir?resid=F6FBCF1880A16630!210&authkey=!AA4CNT499dsekPY&ithint=file%2c.zip
If it's not broken, fix it until it is
|
|
|
|
|
Are you still stuck on this?
I realise it's a bit late, but anyhow...
Assuming your binding is working (didn't test your code, can't at the moment), all you would need to do is add a callback for the dependency property change.
public static readonly DependencyProperty SelectecCategoryProperty =
DependencyProperty.Register("SelectecCategory", typeof(object), typeof(LookupComboControl), new UIPropertyMetadata(new PropertyChangedCallback(OnChanged))););
...
private static void OnChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var control = obj as LookupComboControl;
control.SetCategoryOnVm();
}
private void SetCategoryOnVm()
{
vm.Category = this.SelectedCategory
}
|
|
|
|