![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
| |
| | #1 (permalink) |
| | Trying to make simple databinding work Have been getting most stuff to work, (I can, for example, access pareameters in XAML from code when they are exposed using x:Name) but rather embarrassingly I cannot get a simple databinding to work. All examples (whether online or in my Oreilly book) seem to involve keywords or constructs that I can only assume have been deprecated recently, as I type them in verbatim but have keywords like "Typename" rejected by the compiler. I'm on VS2005, XP sp2, Nov CTP So here (with extraneous guff stripped out) is what I'm trying to do in C# ----- public partial class GriffButton2 : UserControl { private string buttText; public string ButtText { get { return buttText; } set { buttText = value; } } } in XAML -------- <?Mapping XmlNamespace="local" ClrNamespace="CustomControlDemo" ?> <UserControl x:Class="CustomControlDemo.GriffButton2" xmlns="http://schemas.microsoft.com/winfx/avalon/2005" xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" xmlns:local="local" > <Canvas> <TextBlock Text="{Binding Path=local:ButtText}" /> (OR <TextBlock Text="{Binding Path=ButtText}" /> ) </Canvas> I'm only (for now) trying to set the value once. That is, I'm not trying to dynamically change the text on my control from the code. (I've also not yet managed to successfully set a parameter in my control from another XAML file that is deploying the control. Is there a way of defining (for example) an named integer in the Canvas.Resources section, accessing it from code, and using it as a parameter in , say, a Width parameter for something ) Any pointers to - good webpages where I can see this in action - gaping mistakes in my code Would be hugely appreciated. -- Griff (trying to make an industrial UI with XAML/WPF/c#) |
My System Specs![]() |
| | #2 (permalink) |
| | Re: Trying to make simple databinding work There are 2 problems here. 1) For databinding to work you must be using DependencyProperty rather than CLR properties. 2) For the XAML parser to know there is a property you must have the static GetXXX and SetXXX methods on the class declared as owning the property. public static readonly DependencyProperty buttTextProperty = DependencyProperty.register("buttText", typeof(string), typeof(GriffButton2)); public static string GetButtText(DependencyObject obj) {get {(string) obj.GetValue(ButtTextProperty);}}; Michael "Griff" <Griff@discussions.microsoft.com> wrote in message news:5DFC90BA-D33E-41D9-A66E-8518A41AD4B8@microsoft.com... > Have been getting most stuff to work, (I can, for example, access > pareameters > in XAML from code when they are exposed using x:Name) but rather > embarrassingly I cannot get a simple databinding to work. > All examples (whether online or in my Oreilly book) seem to involve > keywords > or constructs that I can only assume have been deprecated recently, as I > type > them in verbatim but have keywords like "Typename" rejected by the > compiler. > I'm on VS2005, XP sp2, Nov CTP > > So here (with extraneous guff stripped out) is what I'm trying to do > > in C# > ----- > public partial class GriffButton2 : UserControl > { > private string buttText; > public string ButtText > { get { return buttText; } set { buttText = value; } } > } > > > in XAML > -------- > <?Mapping XmlNamespace="local" ClrNamespace="CustomControlDemo" ?> > <UserControl x:Class="CustomControlDemo.GriffButton2" > xmlns="http://schemas.microsoft.com/winfx/avalon/2005" > xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" > xmlns:local="local" > > > <Canvas> > <TextBlock Text="{Binding Path=local:ButtText}" /> > > (OR > <TextBlock Text="{Binding Path=ButtText}" /> ) > > </Canvas> > > > > I'm only (for now) trying to set the value once. That is, I'm not trying > to > dynamically change the text on my control from the code. > > (I've also not yet managed to successfully set a parameter in my control > from another XAML file that is deploying the control. Is there a way of > defining (for example) an named integer in the Canvas.Resources section, > accessing it from code, and using it as a parameter in , say, a Width > parameter for something ) > > Any pointers to > - good webpages where I can see this in action > - gaping mistakes in my code > > Would be hugely appreciated. > > -- > Griff > (trying to make an industrial UI with XAML/WPF/c#) |
My System Specs![]() |
| | #3 (permalink) |
| | Re: Trying to make simple databinding work You can call the static method if you like, but it is required for the BAML reader to use to set the property when processing the compiled XAML. The parser used to build the BAML will also not recognize the existence of the property without these methods. You might need the set method, I am not sure if both are required. The set would be: public static void SetButtText(DependencyObject obj) {obj.SetValue(ButtTextProperty, value);} You would use: Text="{Binding Path=ButtText}" To bind to the property. Michael "Griff" <Griff@discussions.microsoft.com> wrote in message news:18BB4D28-036B-4D8C-BE5B-2503768138AD@microsoft.com... > Thanks for your extremely rapid input, Michael. > > Still not sure I have understood. > > i) public static string GetButtText(DependencyObject obj) > > I don't understand what this is for. Is it for me to call from my C# ? > If > so, does that mean I cannot simply set/get the value of my original > property. > Alternatively, is this for the XAML part of the code to access the > property > with ? > If so, shouldn't I be publishing the name of this method somewhere so the > XAML knows how to find it ? > > ii) > > Should my XAML TextBlock have > > Text ="{Binding Path=ButtText}" > or > Text ="{Binding Path=ButtTextproperty}" > > I assume the former. > But I don't get the expected results with either. That is, I have set a > value in my original property but nothing is appearing in my textblock. > > Thanks for your patience. > > -- > Griff > (trying to make an industrial UI with XAML/WPF/c#) > > > "Michael Latta" wrote: > >> There are 2 problems here. >> >> 1) For databinding to work you must be using DependencyProperty rather >> than >> CLR properties. >> 2) For the XAML parser to know there is a property you must have the >> static >> GetXXX and SetXXX methods on the class declared as owning the property. >> >> public static readonly DependencyProperty buttTextProperty = >> DependencyProperty.register("buttText", typeof(string), >> typeof(GriffButton2)); >> public static string GetButtText(DependencyObject obj) {get {(string) >> obj.GetValue(ButtTextProperty);}}; >> >> Michael >> >> >> >> "Griff" <Griff@discussions.microsoft.com> wrote in message >> news:5DFC90BA-D33E-41D9-A66E-8518A41AD4B8@microsoft.com... >> > Have been getting most stuff to work, (I can, for example, access >> > pareameters >> > in XAML from code when they are exposed using x:Name) but rather >> > embarrassingly I cannot get a simple databinding to work. >> > All examples (whether online or in my Oreilly book) seem to involve >> > keywords >> > or constructs that I can only assume have been deprecated recently, as >> > I >> > type >> > them in verbatim but have keywords like "Typename" rejected by the >> > compiler. >> > I'm on VS2005, XP sp2, Nov CTP >> > >> > So here (with extraneous guff stripped out) is what I'm trying to do >> > >> > in C# >> > ----- >> > public partial class GriffButton2 : UserControl >> > { >> > private string buttText; >> > public string ButtText >> > { get { return buttText; } set { buttText = value; } } >> > } >> > >> > >> > in XAML >> > -------- >> > <?Mapping XmlNamespace="local" ClrNamespace="CustomControlDemo" ?> >> > <UserControl x:Class="CustomControlDemo.GriffButton2" >> > xmlns="http://schemas.microsoft.com/winfx/avalon/2005" >> > xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" >> > xmlns:local="local" >> > > >> > <Canvas> >> > <TextBlock Text="{Binding Path=local:ButtText}" /> >> > >> > (OR >> > <TextBlock Text="{Binding Path=ButtText}" /> ) >> > >> > </Canvas> >> > >> > >> > >> > I'm only (for now) trying to set the value once. That is, I'm not >> > trying >> > to >> > dynamically change the text on my control from the code. >> > >> > (I've also not yet managed to successfully set a parameter in my >> > control >> > from another XAML file that is deploying the control. Is there a way >> > of >> > defining (for example) an named integer in the Canvas.Resources >> > section, >> > accessing it from code, and using it as a parameter in , say, a Width >> > parameter for something ) >> > >> > Any pointers to >> > - good webpages where I can see this in action >> > - gaping mistakes in my code >> > >> > Would be hugely appreciated. >> > >> > -- >> > Griff >> > (trying to make an industrial UI with XAML/WPF/c#) >> >> >> |
My System Specs![]() |
| | #4 (permalink) |
| | RE: Trying to make simple databinding work Michael. I was a bit confused so, with your code to get me started, I tried to get my head round it more. I adapted a code sample from http://winfx.msdn.microsoft.com to get the code below and this makes more sense to me. (ie I understand what it is doing). It does not, however, provide the methods you were describing. ---c#---- public static readonly DependencyProperty ButtTextProperty = DependencyProperty.Register("ButtText", typeof(string), typeof(GriffButton2)); public string ButtText { get { return (string)GetValue(ButtTextProperty); } set { SetValue(ButtTextProperty, value); } } ---XAML--- <TextBlock Text ="{Binding Path=ButtText}"/> --------- But (more importantly) it still doesn't actually do the job either. Sure it compiles OK but my textblock still has no text in... I still find that every few compiles I have to restart VS05, does anyone else have this too ? -- Griff (trying to make an industrial UI with XAML/WPF/c#) "Griff" wrote: > Have been getting most stuff to work, (I can, for example, access pareameters > in XAML from code when they are exposed using x:Name) but rather > embarrassingly I cannot get a simple databinding to work. > All examples (whether online or in my Oreilly book) seem to involve keywords > or constructs that I can only assume have been deprecated recently, as I type > them in verbatim but have keywords like "Typename" rejected by the compiler. > I'm on VS2005, XP sp2, Nov CTP > > So here (with extraneous guff stripped out) is what I'm trying to do > > in C# > ----- > public partial class GriffButton2 : UserControl > { > private string buttText; > public string ButtText > { get { return buttText; } set { buttText = value; } } > } > > > in XAML > -------- > <?Mapping XmlNamespace="local" ClrNamespace="CustomControlDemo" ?> > <UserControl x:Class="CustomControlDemo.GriffButton2" > xmlns="http://schemas.microsoft.com/winfx/avalon/2005" > xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" > xmlns:local="local" > > > <Canvas> > <TextBlock Text="{Binding Path=local:ButtText}" /> > > (OR > <TextBlock Text="{Binding Path=ButtText}" /> ) > > </Canvas> > > > > I'm only (for now) trying to set the value once. That is, I'm not trying to > dynamically change the text on my control from the code. > > (I've also not yet managed to successfully set a parameter in my control > from another XAML file that is deploying the control. Is there a way of > defining (for example) an named integer in the Canvas.Resources section, > accessing it from code, and using it as a parameter in , say, a Width > parameter for something ) > > Any pointers to > - good webpages where I can see this in action > - gaping mistakes in my code > > Would be hugely appreciated. > > -- > Griff > (trying to make an industrial UI with XAML/WPF/c#) |
My System Specs![]() |
| | #5 (permalink) |
| | Re: Trying to make simple databinding work Your correction is correct, I was typing this off the top of my head. "value" might even be a keyword so you should probably use some other name for that parameter. I have not gotten it to work without the static methods. They are for sure required for attached properties, and appear to be required for all properties. When do you set the initial value? I have found that if the target of the binding does not have a value it does not do the binding. This is mostly an issue with collection properties not simple string properties like this case. Michael "Griff" <Griff@discussions.microsoft.com> wrote in message news:E6F0CA75-3F93-4C3E-9977-D50D347434FA@microsoft.com... > You wrote > > public static void SetButtText(DependencyObject obj) > {obj.SetValue(ButtTextProperty, value);} > > Should that be > > public static void SetButtText(DependencyObject obj, string value ) > {obj.SetValue(ButtTextProperty, value);} > > The compiler seems not to recognise "value" here like it would in a > Property declaration > -- > Griff > (trying to make an industrial UI with XAML/WPF/c#) > > > "Michael Latta" wrote: > >> You can call the static method if you like, but it is required for the >> BAML >> reader to use to set the property when processing the compiled XAML. The >> parser used to build the BAML will also not recognize the existence of >> the >> property without these methods. You might need the set method, I am not >> sure if both are required. The set would be: >> >> public static void SetButtText(DependencyObject obj) >> {obj.SetValue(ButtTextProperty, value);} >> >> You would use: >> >> Text="{Binding Path=ButtText}" >> >> To bind to the property. >> >> Michael >> >> >> "Griff" <Griff@discussions.microsoft.com> wrote in message >> news:18BB4D28-036B-4D8C-BE5B-2503768138AD@microsoft.com... >> > Thanks for your extremely rapid input, Michael. >> > >> > Still not sure I have understood. >> > >> > i) public static string GetButtText(DependencyObject obj) >> > >> > I don't understand what this is for. Is it for me to call from my C# ? >> > If >> > so, does that mean I cannot simply set/get the value of my original >> > property. >> > Alternatively, is this for the XAML part of the code to access the >> > property >> > with ? >> > If so, shouldn't I be publishing the name of this method somewhere so >> > the >> > XAML knows how to find it ? >> > >> > ii) >> > >> > Should my XAML TextBlock have >> > >> > Text ="{Binding Path=ButtText}" >> > or >> > Text ="{Binding Path=ButtTextproperty}" >> > >> > I assume the former. >> > But I don't get the expected results with either. That is, I have set >> > a >> > value in my original property but nothing is appearing in my textblock. >> > >> > Thanks for your patience. >> > >> > -- >> > Griff >> > (trying to make an industrial UI with XAML/WPF/c#) >> > >> > >> > "Michael Latta" wrote: >> > >> >> There are 2 problems here. >> >> >> >> 1) For databinding to work you must be using DependencyProperty rather >> >> than >> >> CLR properties. >> >> 2) For the XAML parser to know there is a property you must have the >> >> static >> >> GetXXX and SetXXX methods on the class declared as owning the >> >> property. >> >> >> >> public static readonly DependencyProperty buttTextProperty = >> >> DependencyProperty.register("buttText", typeof(string), >> >> typeof(GriffButton2)); >> >> public static string GetButtText(DependencyObject obj) {get {(string) >> >> obj.GetValue(ButtTextProperty);}}; >> >> >> >> Michael >> >> >> >> >> >> >> >> "Griff" <Griff@discussions.microsoft.com> wrote in message >> >> news:5DFC90BA-D33E-41D9-A66E-8518A41AD4B8@microsoft.com... >> >> > Have been getting most stuff to work, (I can, for example, access >> >> > pareameters >> >> > in XAML from code when they are exposed using x:Name) but rather >> >> > embarrassingly I cannot get a simple databinding to work. >> >> > All examples (whether online or in my Oreilly book) seem to involve >> >> > keywords >> >> > or constructs that I can only assume have been deprecated recently, >> >> > as >> >> > I >> >> > type >> >> > them in verbatim but have keywords like "Typename" rejected by the >> >> > compiler. >> >> > I'm on VS2005, XP sp2, Nov CTP >> >> > >> >> > So here (with extraneous guff stripped out) is what I'm trying to do >> >> > >> >> > in C# >> >> > ----- >> >> > public partial class GriffButton2 : UserControl >> >> > { >> >> > private string buttText; >> >> > public string ButtText >> >> > { get { return buttText; } set { buttText = >> >> > lue; } } >> >> > } >> >> > >> >> > >> >> > in XAML >> >> > -------- >> >> > <?Mapping XmlNamespace="local" ClrNamespace="CustomControlDemo" ?> >> >> > <UserControl x:Class="CustomControlDemo.GriffButton2" >> >> > xmlns="http://schemas.microsoft.com/winfx/avalon/2005" >> >> > xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" >> >> > xmlns:local="local" >> >> > > >> >> > <Canvas> >> >> > <TextBlock Text="{Binding Path=local:ButtText}" /> >> >> > >> >> > (OR >> >> > <TextBlock Text="{Binding Path=ButtText}" /> ) >> >> > >> >> > </Canvas> >> >> > >> >> > >> >> > >> >> > I'm only (for now) trying to set the value once. That is, I'm not >> >> > trying >> >> > to >> >> > dynamically change the text on my control from the code. >> >> > >> >> > (I've also not yet managed to successfully set a parameter in my >> >> > control >> >> > from another XAML file that is deploying the control. Is there a >> >> > way >> >> > of >> >> > defining (for example) an named integer in the Canvas.Resources >> >> > section, >> >> > accessing it from code, and using it as a parameter in , say, a >> >> > Width >> >> > parameter for something ) >> >> > >> >> > Any pointers to >> >> > - good webpages where I can see this in action >> >> > - gaping mistakes in my code >> >> > >> >> > Would be hugely appreciated. >> >> > >> >> > -- >> >> > Griff >> >> > (trying to make an industrial UI with XAML/WPF/c#) >> >> >> >> >> >> >> >> >> |
My System Specs![]() |
| | #6 (permalink) |
| | Re: Trying to make simple databinding work Michael Latta wrote: > Your correction is correct, I was typing this off the top of my head. > "value" might even be a keyword so you should probably use some other name > for that parameter. > > I have not gotten it to work without the static methods. They are for sure > required for attached properties, and appear to be required for all > properties. > > When do you set the initial value? I have found that if the target of the > binding does not have a value it does not do the binding. This is mostly an > issue with collection properties not simple string properties like this > case. > > Michael > > > > "Griff" <Griff@discussions.microsoft.com> wrote in message > news:E6F0CA75-3F93-4C3E-9977-D50D347434FA@microsoft.com... > >>You wrote >> >>public static void SetButtText(DependencyObject obj) >>{obj.SetValue(ButtTextProperty, value);} >> >>Should that be >> >>public static void SetButtText(DependencyObject obj, string value ) >>{obj.SetValue(ButtTextProperty, value);} >> >>The compiler seems not to recognise "value" here like it would in a >>Property declaration >>-- >>Griff >>(trying to make an industrial UI with XAML/WPF/c#) >> >> >>"Michael Latta" wrote: >> >> >>>You can call the static method if you like, but it is required for the >>>BAML >>>reader to use to set the property when processing the compiled XAML. The >>>parser used to build the BAML will also not recognize the existence of >>>the >>>property without these methods. You might need the set method, I am not >>>sure if both are required. The set would be: >>> >>>public static void SetButtText(DependencyObject obj) >>>{obj.SetValue(ButtTextProperty, value);} >>> >>>You would use: >>> >>>Text="{Binding Path=ButtText}" >>> >>>To bind to the property. >>> >>>Michael >>> >>> >>>"Griff" <Griff@discussions.microsoft.com> wrote in message >>>news:18BB4D28-036B-4D8C-BE5B-2503768138AD@microsoft.com... >>> >>>>Thanks for your extremely rapid input, Michael. >>>> >>>>Still not sure I have understood. >>>> >>>>i) public static string GetButtText(DependencyObject obj) >>>> >>>>I don't understand what this is for. Is it for me to call from my C# ? >>>>If >>>>so, does that mean I cannot simply set/get the value of my original >>>>property. >>>>Alternatively, is this for the XAML part of the code to access the >>>>property >>>>with ? >>>>If so, shouldn't I be publishing the name of this method somewhere so >>>>the >>>>XAML knows how to find it ? >>>> >>>>ii) >>>> >>>>Should my XAML TextBlock have >>>> >>>>Text ="{Binding Path=ButtText}" >>>>or >>>>Text ="{Binding Path=ButtTextproperty}" >>>> >>>>I assume the former. >>>>But I don't get the expected results with either. That is, I have set >>>>a >>>>value in my original property but nothing is appearing in my textblock. >>>> >>>>Thanks for your patience. >>>> >>>>-- >>>>Griff >>>>(trying to make an industrial UI with XAML/WPF/c#) >>>> >>>> >>>>"Michael Latta" wrote: >>>> >>>> >>>>>There are 2 problems here. >>>>> >>>>>1) For databinding to work you must be using DependencyProperty rather >>>>>than >>>>>CLR properties. >>>>>2) For the XAML parser to know there is a property you must have the >>>>>static >>>>>GetXXX and SetXXX methods on the class declared as owning the >>>>>property. >>>>> >>>>>public static readonly DependencyProperty buttTextProperty = >>>>>DependencyProperty.register("buttText", typeof(string), >>>>>typeof(GriffButton2)); >>>>>public static string GetButtText(DependencyObject obj) {get {(string) >>>>>obj.GetValue(ButtTextProperty);}}; >>>>> >>>>>Michael >>>>> >>>>> >>>>> >>>>>"Griff" <Griff@discussions.microsoft.com> wrote in message >>>>>news:5DFC90BA-D33E-41D9-A66E-8518A41AD4B8@microsoft.com... >>>>> >>>>>>Have been getting most stuff to work, (I can, for example, access >>>>>>pareameters >>>>>>in XAML from code when they are exposed using x:Name) but rather >>>>>>embarrassingly I cannot get a simple databinding to work. >>>>>>All examples (whether online or in my Oreilly book) seem to involve >>>>>>keywords >>>>>>or constructs that I can only assume have been deprecated recently, >>>>>>as >>>>>>I >>>>>>type >>>>>>them in verbatim but have keywords like "Typename" rejected by the >>>>>>compiler. >>>>>>I'm on VS2005, XP sp2, Nov CTP >>>>>> >>>>>>So here (with extraneous guff stripped out) is what I'm trying to do >>>>>> >>>>>>in C# >>>>>>----- >>>>>>public partial class GriffButton2 : UserControl >>>>>> { >>>>>> private string buttText; >>>>>> public string ButtText >>>>>> { get { return buttText; } set { buttText = >>>>>>lue; } } >>>>>> } >>>>>> >>>>>> >>>>>>in XAML >>>>>>-------- >>>>>><?Mapping XmlNamespace="local" ClrNamespace="CustomControlDemo" ?> >>>>>><UserControl x:Class="CustomControlDemo.GriffButton2" >>>>>> xmlns="http://schemas.microsoft.com/winfx/avalon/2005" >>>>>> xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" >>>>>> xmlns:local="local" >>>>>> > >>>>>><Canvas> >>>>>><TextBlock Text="{Binding Path=local:ButtText}" /> >>>>>> >>>>>>(OR >>>>>><TextBlock Text="{Binding Path=ButtText}" /> ) >>>>>> >>>>>></Canvas> >>>>>> >>>>>> >>>>>> >>>>>>I'm only (for now) trying to set the value once. That is, I'm not >>>>>>trying >>>>>>to >>>>>>dynamically change the text on my control from the code. >>>>>> >>>>>>(I've also not yet managed to successfully set a parameter in my >>>>>>control >>>>>>from another XAML file that is deploying the control. Is there a >>>>>>way >>>>>>of >>>>>>defining (for example) an named integer in the Canvas.Resources >>>>>>section, >>>>>>accessing it from code, and using it as a parameter in , say, a >>>>>>Width >>>>>>parameter for something ) >>>>>> >>>>>>Any pointers to >>>>>>- good webpages where I can see this in action >>>>>>- gaping mistakes in my code >>>>>> >>>>>>Would be hugely appreciated. >>>>>> >>>>>>-- >>>>>>Griff >>>>>>(trying to make an industrial UI with XAML/WPF/c#) >>>>> >>>>> >>>>> >>> >>> > > Hmm... any ideas what to do when you are attempting to bind to list data dynamically (ie. dynamically setting up for certain pieces of your display to specific cells in a DataTable)? I'm trying to build a custom control that represents a grid. All this grid should be doing is displaying the data from a DataTable, therefore each individual cell in the grid needs to be dynamically bound to a cell in the DataTable. To start with, I've created the Grid as a custom control. The actual control contains a top level layout grids which contains child grids (one for columns, one for headers, then another for the content itself, all layed out in XAML. Right now each cell is getting displayed by placing a textbox in that grid position, later on I'd like to replace this with something more lightweight. These are snippets of some relevant bits from the C# code behind: public partial class DataGrid : ItemsControl { public static readonly DependencyProperty DataViewProperty = null; static DataGrid() // static initializer { // initializing dependency property DataViewProperty = DependencyProperty.Register( "DataView", typeof(DataView), typeof(DataGrid), new FrameworkPropertyMetadata (null, FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(dataViewChanged), null)); // CLR property wrapper public DataView DataView { get {return (DataView)GetValue(DataViewProperty);} set {SetValue(DataViewProperty, value); } } // fills the dataContentGrid with cells (this snippet assumes // I've omitted the chunk that creates Row and Column // definitions to display here... This method get's called when // the window is loaded to initially populate the table private void addContent() { DataTable dt = this.DataView.Table; int maxRows = dt.Rows.Count; int maxColumns = dt.Columns.Count; for (int rowCount = 0; rowCount < maxRows; rowCount++) { for (int columnCount = 0; columnCount < maxColumns; columnCount++) { TextBlock tb = new TextBlock(); // Set up binding to from the // TextBlock's Text property to the // correct cell of the DataTable. Binding b = new Binding("Table.Rows[" + rowCount + "][" + columnCount + "]"); b.Mode = BindingMode.TwoWay; b.Source = this.DataView; tb.SetBinding(TextBlock.TextProperty, b); // Add the text block to the Grid. Grid.SetColumn(tb, columnCount); Grid.SetRow(tb, rowCount); dataContentGrid.Children.Add(tb); } } } } Okay, now that we've got that, I've created a class which extends DataView (called MyDataView), which simply instantiates a DataTable, fills it with data and sets it's Table reference (inherited from DataView) to this table. Finally, I instantiate this all in my window.xaml file, creating the custom grid control, a MyDataView and setting the grid's DataView property to this datasource: <?Mapping XmlNamespace="local" ClrNamespace="Jason.Controls"?> <Window x:Class="Jason.Controls.Window1" xmlns="http://schemas.microsoft.com/winfx/avalon/2005" xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" Title="DataGrid Control" xmlns:cc="local" xmlns:data="systemdata" Loaded="OnLoad" > <Window.Resources> <cc:MyDataView x:Key="testDataView" /> </Window.Resources> <Grid> <cc ataGrid DataView="{DynamicResource testDataView}" /></Grid> </Window> That's a mouthful, isn't it? The grid displays the first time with all of the data from the datatable. Unfortunately, when I write code that changes elements in the DataTable, the changes are never reflected in the grid display. I thought the binding set up: Binding b = new Binding("Table.Rows[" + rowCount + "][" + columnCount + "]"); b.Mode = BindingMode.TwoWay; b.Source = this.DataView; tb.SetBinding(TextBlock.TextProperty, b); would have taken care of this. Changes in the data in the DataTable really should be reflected back to the TextBlock Text which is bound to it, right? No luck though. I've also tried calling AcceptChanges() on the DataTable once I make changes, and that has had no effect either. I CAN make this thing work however by setting up the notification myself. I make the MyDataView class implement INotifyCollectionChanged, then call the OnPropertyChanged(string propname) method from my code that changes the DataTable, passing the name of the DataView property. Then I make my custom grid control register for notifications on it's DataView's CollectionChanged event: DataView.CollectionChanged += onDataViewChanged; and implement the onDataViewChanged method to clear and rebuild the table from the DataView's contents. However isn't this defeating the purpose of databinding? I shouldn't have to be doing this myself. Can someone tell me whether I was even on the right track here? Or am I way off? Thanks for any advice! Jason |
My System Specs![]() |
| | #7 (permalink) |
| | Re: Trying to make simple databinding work A bit of clarification here!!!! public static void SetButtText/GetButtText is ONLY used if your DependencyProperty is *an attached property*. This means it's being used on other objects (like Grid.Row, or Canvas.Top). For standard properties on a FrameworkElement use: public static readonly DependencyProperty ButtTextProperty = DependencyProperty.Register("ButtText", typeof(string), typeof(MyButtonClass)); public string ButtText { get { return (string)this.GetValue(ButtTextProperty); } set { this.SetValue(ButtTextProperty, value); } } |
My System Specs![]() |
| | #8 (permalink) |
| | Re: Trying to make simple databinding work Jason- A couple quick pointers, but please post if you have more questions- Deriving from ItemsControl is almost never what you want to do, it's very tempting, but I've never seen someone who did it and should have done it. Instead, you should take a look at ItemsControl.ItemPanel property. By the looks of your code, I'd say all you need to do is put a UniformGrid in there then bind the Rows and Columns properties. Then for your content, make a DataTemplate for ItemsControl.ItemTemplate. Now, the real problem- DataTable doesn't generate property changes- you change the contents, but nothing notifies the UI that the stuff changed. To get this, you need to make a wrapper for the DataTable that generates the necessary events (INotifyCollectionChanged), or exposes the data as an ObservableCollection. The ObservableCollection is a super lame conversion, and Avalon has completely ignored the entire System.Data framework. I don't know what to say, but the two don't communicate. Sorry. |
My System Specs![]() |
| | #9 (permalink) |
| | Re: Trying to make simple databinding work I can answer some of your questions. See below. "Jason Dolinger" <jdolinger@lab49.com> wrote in message news:eS0FbyKBGHA.516@TK2MSFTNGP15.phx.gbl... > auto239436@hushmail.com wrote: >> Jason- >> A couple quick pointers, but please post if you have more questions- >> >> Deriving from ItemsControl is almost never what you want to do, it's >> very tempting, but I've never seen someone who did it and should have >> done it. >> >> Instead, you should take a look at ItemsControl.ItemPanel property. By >> the looks of your code, I'd say all you need to do is put a UniformGrid >> in there then bind the Rows and Columns properties. >> >> Then for your content, make a DataTemplate for >> ItemsControl.ItemTemplate. >> >> Now, the real problem- DataTable doesn't generate property changes- you >> change the contents, but nothing notifies the UI that the stuff >> changed. To get this, you need to make a wrapper for the DataTable that >> generates the necessary events (INotifyCollectionChanged), or exposes >> the data as an ObservableCollection. >> >> The ObservableCollection is a super lame conversion, and Avalon has >> completely ignored the entire System.Data framework. I don't know what >> to say, but the two don't communicate. Sorry. >> > > Thanks for the great responses! A few followups... > > 1. The reason I used ItemsControl is that I'm trying to make this grid a > generic reusable control (in the absence of one provided by MS). I should > be able to hook it up to any datasource and have it display contents the > way the Winforms DataGrid did. I don't quite understand how > ItemsControl.ItemPanel can achieve this. ItemsControl just arranges its contents as child elements of a panel. What panel it uses is defined in ItemsControl.ItemPanel, which in Nov CTP is a template that can only have one element. This allows you to control the presentation of the items without having to subclass ItemsControl itself. The panel class can have all the fancy layout logic you like. You can also use the other properties like ItemTemplate, ItemTemplateSelector or simple DataTemplates to control the presentation of each item in the collection. The combinations give a huge amount of flexibility. > > 2. It seems like I need something a lot more sophisticated than just a > simple data template to lay out the grid content. Were you suggesting > that we remove the dataContentGrid entirely, and have the template be > smart enough to display all of the cells? Or should there be a single > data template that is applied to each cell? As stated above you can individually select the data template for items using ItemTemplateSelector, or be uniform using ItemTemplate, or rely on DataTemplate definitions for the items being presented (useful when they are data objects to be presented uniformly all over your application). > > 3. When you say that DataTable doesn't generate property changes, that > means that it won't work with databinding in a WPF world then, right? > DataTable is still the same object from the .NET framework, and it clearly > communicates with the .NET DataGrid to notify of changes. So the problem > is that WPF relies on the Dependency Property? And just adding a Binding > class isn't enough... I am not sure what change notification WinForms uses for DataGrid but from his answer it is not the same as WPF and an adapter would be needed. This can be a simple object that listens for the WinForms type notifications and sends out the WPF type notifications, then provides access to the contents of the collection. > > Thanks for your help! > Jason |
My System Specs![]() |
| | #10 (permalink) |
| | Re: Trying to make simple databinding work Michael, I'm starting to feel stupider by the day but I have not managed a single working demo with simple databinding. Every demo I can find anywhere in the documentation either features pre NovCTP syntax or crashes with no helpful runtime errors. For example, what do I have to actually do to the code below to make it display text in the textblock that came from the code behind. ? I understood from the other posts to this thread that the SetMyText and GetMyText methods are only required for "attached" properties. Things I cannot get my head round (aside from the "why doesn't my example actually work?" question) include - why is the DependencyProperty that I create a static object ? I'd have thought I'd want one for each and every instance of the object. - in the SetXXXX and GetXXXX methods you were referring to obj (a DependencyObject) but my class is originally descended from a dependency object so why is another object being called into play ? Is it instantiated "out of sight" by the XAML side of things ? Anyway, I figured I'd get something basic working and work outwards. Ultimately I want to create a user control, so that future users (in code or XAML) simply set a binding and supply values into the parameters. The code below will compile, not crash, yet produces no text in the textblock. ----c#--------- namespace DataBindingDemo { public partial class Window1 : Window { public static DependencyProperty MyTextProperty = DependencyProperty.Register("MyText", typeof(string), typeof(Window1)); public string MyText { get { return (string)this.GetValue(MyTextProperty);} set { this.SetValue(MyTextProperty, value); } } public Window1() { MyText = "Starting value set from constructor"; InitializeComponent(); } } } ----XAML--- <?Mapping XmlNamespace="local" ClrNamespace="DataBindingDemo"?> <Window x:Class="DataBindingDemo.Window1" x:Name="MainWindow" xmlns="http://schemas.microsoft.com/winfx/avalon/2005" xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" Title="DataBindingDemo" xmlns:local="local" > <StackPanel> <TextBlock Background="Red" Text="{Binding Path=MyText}"/> </StackPanel> </Window> ------- Griff (trying to make an industrial UI with XAML/WPF/c#) |
My System Specs![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| how do I make it work?? | Vista mail | |||
| I cant get simple screensavers to work! Help please! | General Discussion | |||
| Scripting neophyte - why does this simple script not work? | VB Script | |||
| Can't make New Simple Volume | Vista performance & maintenance | |||