I have just succeeded to use, on c#, the property Binding, I saw two ways to do this:
Binding="{Binding Path=DataBinded}" and Binding="{Binding Path=.DataBinded}"
They are both working, but if there is two ways to write, it's for a reason...What's the difference between Path= and Path=. ?
usually . refers to the preceding object and allow you to point to the sub properties, you may consider it as a separator as well. as mentioned in the question there is no preceding object so in this case the . refers to the DataContext itself and so Binding="{Binding Path=DataBinded}" and Binding="{Binding Path=.DataBinded}" are equal
you may consider the following example when you want to bind some text value directly
<TextBlock Text="{Binding}" />
or
<TextBlock Text="{Binding Path=.}" />
both of the example above points to the DataContext of the TextBlock and will bind to the same.
Using a period path ("Path=.") will bind to the current source :)
You can read the docs here under remarks seccion (last point)
Related
I am very new to WPF in C# and I am stuck working on an application made to (among other things) calculate the total number of items on a list. I want to print a label with that number/the sum and in tutorials I have seen people call labelname.Text in their source code, but when I try to do the same I don't have that option.
My Windows application design
It is in Danish, but what I need is the sum of "Antal" from the table printed on a label next to "Samlet antal varer:" to the right of the table.
My DataGrid:
<DataGrid ColumnWidth="*" CanUserAddRows="False" x:Name="StockList" Margin="57,23,453,261">
<!--Column Header Text & Bindings -->
<DataGrid.Columns>
<DataGridTextColumn Header="Vare" Binding="{Binding vare}" Width="auto"/>
<DataGridTextColumn Header="Pris" Binding="{Binding pris}" Width="50"/>
<DataGridTextColumn Header="Antal" Binding="{Binding antal}" Width="50"/>
<DataGridTextColumn Header="Samlet pris" Binding="{Binding samletPris}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
My Labels:
<!-- labels -->
<Label x:Name="lblSamletVarer" HorizontalAlignment="Left" Margin="637,142,0,0" VerticalAlignment="Top"/>
<Label x:Name="lblSamletPrisEkskl" HorizontalAlignment="Left" Margin="637,192,0,0" VerticalAlignment="Top"/>
<Label x:Name="lblSamletPrisInkl" HorizontalAlignment="Left" Margin="637,242,0,0" VerticalAlignment="Top"/>
I hope it all makes sense. Please reach out if you need more information in order to help.
Try
<TextBlock x:Name="Label1" Text="{Binding Path=Label1Value}"/>
in XAML to replace your label markup (a better option than a Label) then provide a value for it in your ViewModel or code-behind; you can provide a literal value as I've shown below or use whatever logic you like to compute a value at runtime and return that. A TextBlock uses a OneWay binding by default since it is read-only, so you don't need to provide a setter or PropertyChanged notification.
public string Label1Value
{
get { return "This string in your TextBlock"; }
}
Obviously, use whatever more appropriate identifiers you like for "Label1Value" and "Label1"!
It isn't clear what you are trying to bind the DataGridTextColumn elements to in your code. You can bind directly from one control to another using the "ElementName" syntax within the binding expression, but since you need to compute something from your DataGridTextColumn, I assume you'll bind that to something in your ViewModel or code-behind and calculate the value there before passing it back.
I've been a long time lurker on SO and have only recently decided to set up an account. I've been spending quite a lot of hours trying to solve this problem I've been having without asking but I here it is.
What I'm trying to accomplish:
I have a list of strings, e.g: Mango, Banana, Melon (let's call it fruits) and I want to display it as a table in XAML (WPF), where it appears as row values on the left side, and the right side will be combo boxes that will allow users to pick a value. I'm currently stuck on the displaying part of this problem. I decided to use a DataGrid to display the list, and the code behind will do the data bindings.
Here's the XAML part of it:
<DataGrid x:Name="FruitDataGrid" Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6" HorizontalAlignment="Left" Width="1188" AutoGenerateColumns="False">
<!-- If AutoGenerateColumns was true only the length is displayed.-->
<DataGrid.Columns>
<DataGridTextColumn x:Name="fruitsDisplay" Header="Fruits" MinWidth="450" IsReadOnly="True" />
<DataGridComboBoxColumn Header="Number of Boxes" MinWidth ="200" CanUserResize="True" Width="*"></DataGridComboBoxColumn>
</DataGrid.Columns>
Code Behind so far has been really simple, and after many attempts this is the most recent one.
private void populateFruitList()
{
FruitDataGrid.DataContext = fruitDataTable;
//Binds a datatable instance to the datagrid, does not display anything.
}
What I've been attempting:
Turn the List of Strings into an Observable Collection, or Enumerable, and do FruitDataGrid.itemsource = fruitsObservable;
The above method works, except that it will only display the length of each string value (if autogeneratecolumns is true), which is not what I want. If autogeneratecolumns was false then I can see the rows being shown, but not the string values.
I also tried using DataView or DataGridView but I failed to define it in the XAML, VS2012 says that there isn't such a thing.
I've been trying to do data binding as well as the MSDN Article says, but VS2012 never manages to bind to the list properly.
I then attempted to change my list into a datatable and [use a datagridview as specified here but again the XAML tells me it is not a valid class][2]. I am also aware of the performance impact datagridview might have but at this point I just want to display a table really.
I've also seen that some tutorials use a DataGrid.datasource method but that isn't in the DataGrid I want, I think it's a different class? (the DataGrid I am attempting to use is System.Windows.Controls.DataGrid, and the other one is in Windows Forms [As shown here][3])
Thanks again for taking the time to look into this.
EDIT
Trying to bind to the list in XAML this way:
<DataGrid x:Name="FruitDataGrid" Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6" HorizontalAlignment="Left" Width="1188" AutoGenerateColumns="False" ItemsSource="fruitDataList">
I get the error in XAML "The type converter for IEnumerable does not support converting from a string" which I think is because I'm doing it wrong. The table now shows a lot of empty rows though.
Trying ItemSource="{Binding fruitDataList}" (where fruitDataList is a List) yields a blank table, and an error in VS for BindingExpression path error.
To sum up what the previous issue was, thanks to Muds, and hours of trying, the Binding in the XAML was not properly done.
In FruitDataGrid, this property should be written as ItemSource="{Binding}" this tells the XAML code to bind to whatever object the DataContext is assigned to in the code behind.
After that, within the DataGrid.Column, this property is needed.
Binding="{Binding Path=.}"
It had to be exactly that for me. lack of the dot or not enclosing it in quotes will not display the fruits.
Thus, for clarity:
In the XAML:
<DataGrid x:Name="FruitDataGrid"
Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6"
HorizontalAlignment="Left" Width="1188"
AutoGenerateColumns="False"
ItemSource="{Binding}">
<!-- If AutoGenerateColumns was true only the length is displayed.-->
<DataGrid.Columns>
<DataGridTextColumn
x:Name="fruitsDisplay"
Header="Fruits" MinWidth="450"
IsReadOnly="True"
Binding="{Binding Path=.}"/> <!--Exactly like this -->
<DataGridComboBoxColumn
Header="Number of Boxes"
MinWidth ="200"
CanUserResize="True" Width="*" />
</DataGrid.Columns>
And then in the codebehind (filename.xaml.xs)
//Anywhere you plan to bind the list in my case FruitList
List<string> fruitList = new List<string>();
fruitList.add("Melon");
fruitList.add("Mango");
fruitList.add("Banana");
FruitDataGrid.DataContext = fruitList;
And now you'll have a very nice list displayed as a table. What killed 2 days of my time was the binding path should have a . (dot) right there, and I was binding to a string instead of an object (you literally bind to a string "fruitList" when you do Binding = {"fruitList"}. This amateur mistake stems from me insufficiently self-learning XAML.
Thanks again, Muds. I'll select yours as the answer because it helped me, and it feels weird accepting my own answer.
Considering your binding is set to your viewmodel correctly.. do this
ItemsSource="{Binding fruitDataList}"
then
<DataGrid.Columns>
<DataGridTextColumn
x:Name="fruitsDisplay"
Binding="{Binding Path=FRUITS_PROPERTY_NAME_IN_COLLECTION}"
Header="Fruits"
MinWidth="450"
IsReadOnly="True" />
<DataGridComboBoxColumn
ItemsSource="{Binding TO_List_of_Numbers}"
Header="Number of Boxes"
MinWidth ="200"
CanUserResize="True" Width="*"></DataGridComboBoxColumn>
I currently have a list of objects in which my RadGridView's ItemsSource is set to. When the property "DoNotContact" of the object in the list has been set to True, I want to hide the information in the cell that contains a Phone number within my RadGridView. As you can see in my XAML, I'm setting the Visibility property within the TextBlock like so:
<telerik:GridViewDataColumn Header="Evening" DataMemberBinding="{Binding Path=EveningPhone}" Width="75" SortMemberPath="EveningPhone">
<telerik:GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Visibility="{Binding Path=DoNotContact, Converter={StaticResource BoolToVisibilityConverter}}">
<Hyperlink Click="MakeEveningCallHandler">
<TextBlock Text="{Binding Path=EveningPhone}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
</telerik:GridViewColumn.CellTemplate>
</telerik:GridViewDataColumn>
When attempting to debug it, the Converter is never hit and although I can see the property "DoNotContact" has been set, the phone number still shows. The converter itself works fine as I've used it in other occasions. Again I only want to hide the information WITHIN the cell for the "Evening" Property, not the actual column itself. Any Ideas what's going wrong here? Thanks a bunch!
The code you provided works for me!
I've got a list view that is populated by a Binding, on a class named House.
Here's an example of my code:
<DataTemplate DataType="house">
<TextBlock Text="{Binding sold_status}" />
</DataTemplate>
As you can see, one of my variable names is sold_status. This is a bool.
I want to show either "SOLD" or "NOT SOLD" for 1 and 0 respectively.
Is it possible to fashion an if statement based on the value?
So just so that you can visualise what I want to achieve:
<DataTemplate DataType="house">
<TextBlock Text="({Binding sold_status} == 1) 'SOLD' else 'NOT SOLD'" />
</DataTemplate>
You'll want to create a Style with DataTriggers in to set the properties as needed. You could also use a converter, but changing UI control properties based on underlying data is exactly what triggers/styles are all about.
..In fact, I can see you're basically 'converting' sold_status to a bit of text. For that, use a converter. I'll post a quick example..
See the top answer here: WPF: Display a bool value as "Yes" / "No" - it has an example converter class you could repurpose.
Look up the IValueConverter interface for an example. Implement the Convert method to return the text you want to display.
You want to use a value converter.
A better approach to this would be to use a converter. Keep the binding as you have done in your first example then have the converter return a string with "Sold" if true etc.
I suggest you to use a DataTrigger. It's quite simple and doesn't require separate converter.
<DataTemplate DataType="house">
<TextBlock x:Name="Status" Text="SOLD" />
<DataTemplate.Triggers>
<DataTrigger Binding="{sold_status}" Value="False">
<Setter TargetName="Status" Property="Text" Value="NOT SOLD"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
I have a Silverlight DataGrid that's being populated with different types of data for each column. I'm trying to figure out how to format some of the contents of the DataGrid's cells, specifically for dates and formatting.
I have a date column that's currently displaying like: 3/11/2010 12:00:00 AM. I would rather it display like 3/14/2010.
I have a number column that's currently displaying like: 51.32. I'd rather it display as currency like $51.32.
I'm not sure how I can go about doing this. I'd prefer to do it in XAML instead of C#, but both solutions are fine.
For reference, here's my XAML so far:
</data:DataGridTextColumn>
<data:DataGridTextColumn Header="Payee"
Binding="{Binding Payee}"/>
<data:DataGridTextColumn Header="Category"
Binding="{Binding Category}"/>
<data:DataGridTextColumn Header="Memo"
Binding="{Binding Memo}"/>
<data:DataGridTextColumn Header="Inflow"
Binding="{Binding Inflow}"/>
<data:DataGridTextColumn Header="Outflow"
Binding="{Binding Outflow}"/>
</data:DataGrid.Columns>
If you have the possibility to wait for the release of Silverlight 4, possibly at Mix10 next week. It has some new features in the binding, like formatting. With Silverlight 4 you can do stuff like:
<TextBox Text="{Binding ReleaseDate, StringFormat='MMM dd, yyyy',
Mode=TwoWay}" />
Shawn Wildermuth has a nice overview of the new features on his blog.
You can use a IValueconverter based on string.Format and bind it in XAML.
Check out how to do it here
Yet another article to address the same