|
Best is, when I show an example:
XAML:
<Window x:Class="WpfApplication2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid x:Name="grid" ShowGridLines="True">
</Grid>
</Window>
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
namespace WpfApplication2
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
ObsCls coll = CreateObsColl();
grid.DataContext = coll;
for (int i = 0; i < 5; i++)
{
RowDefinition row = new RowDefinition();
ColumnDefinition col = new ColumnDefinition();
grid.RowDefinitions.Add(row);
grid.ColumnDefinitions.Add(col);
}
foreach (var item in coll)
{
Grid.SetColumn(item, (int)item.Content);
Grid.SetRow(item, (int)item.Content);
}
Thread t = new Thread(() =>
{
Dispatcher.BeginInvoke(new Action(() =>
{
coll.Clear();
Button b = new Button() { Content = 4 };
Grid.SetRow(b, (int)b.Content);
Grid.SetColumn(b, (int)b.Content);
coll.Add(b);
}));
});
t.Start();
}
private ObsCls CreateObsColl()
{
ObsCls coll = new ObsCls();
coll.Add(new Button() { Content = 1 });
coll.Add(new Button() { Content = 2 });
coll.Add(new Button() { Content = 3 });
return coll;
}
}
}
using System.Collections.ObjectModel;
using System.Windows.Controls;
namespace WpfApplication2
{
class ObsCls : ObservableCollection<Button>
{
}
}
What has to be done to get this working? Help would be really apreciated.
Thanks in advance
|
|
|
|
|
Scratch that last reply - you were already adding child buttons.
It looks like you're trying to use a Grid (Panel) as a DataGrid...
Are you using the right grid type?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
what would be the alternative? As long as there is no DataGrid in WPF.
After all all I want to do is displaying Buttons and Textblocks on certain Positions within a Matrix.
What I do now is cleaning the children of the grid and resetting them each time I change something. Not the best way I think, despite other problems I have with this..
|
|
|
|
|
ezazazel wrote: what would be the alternative? As long as there is no DataGrid in WPF.
There's a nice datagrid here: WPF Toolkit - October 2008 Release[^]
It's not in the .NET framework proper yet, but it's there as an add-on!
Is datagrid functionality what you are looking for or do you have controls
that dynamically change often and/or are always arranged at runtime?
I'm not sure what you're trying to do
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Ok, let's dive in deep:
I have a device where I can connect devices with other devices, a matrix.
The devices on each side send events, e.g OK and FAIL
I want to write a piece of software which has an observable collection with elements (buttons)
created by the information from the events.
This is: two devices connected (IN / OUT)
The Position inside the softwarematrix is generated from indeviceposition=>X and outdeviceposition=>Y
So in the beginning I ask all devices and generate the observablecollection.
A timer request when elapsed all devices for their status.
Let's pretend device1(IN) with device2(OUT) is connected.
This results in a button within the softwarematrix in Grid.SetRow(item, 1) and Grid.SerRow(item,2)
Now the timer requests again and this special IN/OUT combination failed, so the value ISFaulty of the observablecollectionitem is set to true and the softwarematrix displays the button now in red.
As you can see, I did it with grid.Children.Clear and grid.Children.Add when the observablecollection fires the event onCollectionChanged.
What I think is, that there should be a better way, maybe by binding the display directly to the observablecollection.
To get this to work, there need to be rules:
Rule1: PositionX and PositionY inside the softwarematrix are taken out of the properties from the class
Rule2: BackgroundColor is defined by the status of an enumeration
So that's it in short words.
|
|
|
|
|
If you have a fixed number of rows and columns in the grid, you may be able to use a generic ItemsControl with some clever styles and templates. The ItemsControl.ItemsPanel would have the grid definition, and the ItemsTemplate would have a DataTemplate that binds the Grid.Row/Column properties to the associated properties on your object. The colorings could be set using Triggers (maybe DataTrigger instead of regular Trigger) in the template based on the value of an enumeration property.
If you have a dynamic number of rows and columns, it could be done, but is much more difficult because you have to get the actual items panel for your ItemsControl instance. I am fairly certain that this is doable, but it takes a fair bit of code to pull off.
|
|
|
|
|
Actually I'm doing this:
internal class ObsCollection<T> :ObservableCollection<T>
{
private bool _suppressNotification = false;
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
if (item is INotifyPropertyChanged)
(item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(ObsCollection_PropertyChanged);
}
protected override void RemoveItem(int index)
{
if (this[index] is INotifyPropertyChanged)
(this[index] as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(ObsCollection_PropertyChanged);
base.RemoveItem(index);
}
protected override void ClearItems()
{
for (int i = 0; i < this.Count; i++)
{
RemoveItem(i);
}
}
void ObsCollection_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (!_suppressNotification)
base.OnCollectionChanged(e);
}
public void AddRange(IEnumerable<T> list)
{
if (list == null)
throw new ArgumentNullException("list");
_suppressNotification = true;
foreach (T item in list)
{
Add(item);
}
_suppressNotification = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
and in the gridControl
void s_MElementCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
command.SetElementsOnGrid(ref this.grid);
}
internal void SetElementsOnGrid(ref Grid grid)
{
grid.Children.Clear();
SetHeaders(ref grid);
foreach (var item in s_Constructor.s_MElementCollection)
{
Grid.SetColumn(item, item.PositionDevice);
Grid.SetRow(item, item.PositionAntenna);
item.CommandParameter = item;
item.Command = UICommands.uiCommand;
if (item.IsEnabled)
if (item.IsError) item.Background = Brushes.OrangeRed; else item.Background = Brushes.Green;
else item.Background = Brushes.DarkRed;
grid.Children.Add(item);
}
}
Seems to work by now. What do you think about this aproach?
|
|
|
|
|
If you have something that already works, I would stick with it.
Only thing that jumps out at me is that you are passing the Grid by reference. Passing a class parameter by reference is only needed in exceptional circumstances.
|
|
|
|
|
I personally really don't like the idea of having UI elements in the collection
when WPF provides data templating to build the UI for you so you can keep your
UI and data separate.
Given that, your requirements, and the fact that I've never tried making
a custom ItemsControl before, I thought I'd play around with this.
Always fun to learn new stuff!
Here's what I came up with...
ezazazel wrote: Rule1: PositionX and PositionY inside the softwarematrix are taken out of the properties from the class
Rule2: BackgroundColor is defined by the status of an enumeration
Given these rules, I started by creating an "Obs" class, based on the name of your
originally posted "ObsCls" class. This class holds a text string, the row and column
where it should be in the grid, and a status enumeration.
So you can change an Obs objects properties and have the change magically appear in the UI,
I used INotifyPropertyChanged (dependency properties would work fine too).
I also added a class called "ObsList", which is an ObservableCollection of Obs objects.
Here's that:
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.ComponentModel;
namespace MyNamespace
{
public class Obs : INotifyPropertyChanged
{
public enum ObsStatus
{
Off,
On
}
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
OnPropertyChanged("Name");
}
}
private int _row;
public int Row
{
get
{
return _row;
}
set
{
_row = value;
OnPropertyChanged("Row");
}
}
private int _col;
public int Col
{
get
{
return _col;
}
set
{
_col = value;
OnPropertyChanged("Col");
}
}
private ObsStatus _status;
public ObsStatus Status
{
get
{
return _status;
}
set
{
_status = value;
OnPropertyChanged("Status");
}
}
public Obs(string str, int row, int col)
{
Name = str;
Row = row;
Col = col;
Status = ObsStatus.Off;
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
public class ObsList : ObservableCollection<Obs>
{
}
}
I also created a class derived from ObsList to use as static data in the designer:
public class ObsCls_designer : ObsList
{
public ObsCls_designer()
{
Obs newobs = new Obs("1", 0, 0);
newobs.Status = Obs.ObsStatus.Off;
Add(newobs);
newobs = new Obs("2", 1, 1);
newobs.Status = Obs.ObsStatus.On;
Add(newobs);
newobs = new Obs("3", 2, 2);
newobs.Status = Obs.ObsStatus.Off;
Add(newobs);
newobs = new Obs("4", 3, 3);
newobs.Status = Obs.ObsStatus.On;
Add(newobs);
newobs = new Obs("5", 4, 4);
newobs.Status = Obs.ObsStatus.Off;
Add(newobs);
}
}
That's it on the data side.
For the UI, you need an ItemsControl or derived to bind a collection of data to.
Since none of the built-in ItemsControls use a Grid as an ItemsPanel, I needed
to make my own custom ItemsControl. Here's the XAML in its entirety, wrapped in
a Window to test it all:
<Window x:Class="MyNamespace.TestItemsControlGridWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
Title="TestWindow" Height="204" Width="293" ShowInTaskbar="False" WindowStartupLocation="CenterOwner" >
<Window.Resources>
<local:ObsCls_designer x:Key="obsCls_designer" />
<local:ObsItemStyleSelector x:Key="obsItemStyleSelector"/>
</Window.Resources>
<StackPanel Width="Auto" Height="Auto">
<Border Width="Auto" Height="Auto" BorderThickness="1,1,1,1" BorderBrush="#FF505050" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="4,4,4,4">
<Grid Width="Auto" Height="Auto" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ItemsControl Loaded="ItemsControl_Loaded" ItemContainerStyleSelector="{StaticResource obsItemStyleSelector}" ItemsSource="{Binding Source={StaticResource obsCls_designer}}" Width="Auto" Height="Auto" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="25"/>
<RowDefinition Height="Auto" MinHeight="25"/>
<RowDefinition Height="Auto" MinHeight="25"/>
<RowDefinition Height="Auto" MinHeight="25"/>
<RowDefinition Height="Auto" MinHeight="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="50"/>
<ColumnDefinition Width="Auto" MinWidth="50"/>
<ColumnDefinition Width="Auto" MinWidth="50"/>
<ColumnDefinition Width="Auto" MinWidth="50"/>
<ColumnDefinition Width="Auto" MinWidth="50"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Obs}">
<Button Click="Button_Click">
<Button.Style>
<Style TargetType="{x:Type Button}" >
<Setter Property="Content" Value="{Binding Path=Name}"/>
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Background" Value="#80BBBB00"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Status}" Value="On">
<Setter Property="Background" Value="#80FFFF00"/>
<Setter Property="Foreground" Value="#FFFF0000"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
<Button Content="Test" HorizontalAlignment="Center" VerticalAlignment="Center" Click="TestButton_Click"/>
</StackPanel>
</Window>
For simplicity, I inlined all the style and template stuff.
The ItemsControl.ItemTemplate is the key. It determines how items will
appear in the ItemsControl. I used a DataTemplate bound to the Obs type
which contains just a Button.
Here's the code for the ObsItemStyleSelector (thanks Gideon!) used to
bind the Obs.Row/Obs.Col properties to the Grid.Row/Grid.Column attached
properties:
public class ObsItemStyleSelector : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
Obs obs = item as Obs;
ContentPresenter cp = container as ContentPresenter;
if (null != obs && null != cp)
{
Binding binding = new Binding("Row");
binding.Source = obs;
cp.SetBinding(Grid.RowProperty, binding);
binding = new Binding("Col");
binding.Source = obs;
cp.SetBinding(Grid.ColumnProperty, binding);
}
return null;
}
}
To tie it all together and try it out, here's the code-behind for the test window:
public partial class TestItemsControlGridWindow : Window
{
private ObsList obslist = new ObsList();
public TestItemsControlGridWindow()
{
InitializeComponent();
}
private void ItemsControl_Loaded(object sender, RoutedEventArgs e)
{
ItemsControl itemscontrol = sender as ItemsControl;
itemscontrol.ItemsSource = obslist;
Obs newobs = new Obs("1", 0, 0);
newobs.Status = Obs.ObsStatus.Off;
obslist.Add(newobs);
newobs = new Obs("2", 1, 1);
newobs.Status = Obs.ObsStatus.On;
obslist.Add(newobs);
newobs = new Obs("3", 2, 2);
newobs.Status = Obs.ObsStatus.Off;
obslist.Add(newobs);
newobs = new Obs("4", 3, 3);
newobs.Status = Obs.ObsStatus.On;
obslist.Add(newobs);
newobs = new Obs("5", 4, 4);
newobs.Status = Obs.ObsStatus.Off;
obslist.Add(newobs);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Obs obs = button.DataContext as Obs;
if (obs.Status == Obs.ObsStatus.Off)
obs.Status = Obs.ObsStatus.On;
else
obs.Status = Obs.ObsStatus.Off;
}
private void TestButton_Click(object sender, RoutedEventArgs e)
{
obslist[2].Col = 0;
Obs newobs = new Obs("6", 0, 3);
newobs.Status = Obs.ObsStatus.Off;
obslist.Add(newobs);
}
}
ItemsControl_Loaded() sets the ItemControl's ItemsSource to a fresh empty ObsList
Instead of using the designer data.
Button_Click() toggles the Obs object State On or Off to test the associated UI tigger.
TestButton_Click() tests moving an item and adding an item, both by just chaging the
objects properties!
Mark Salsbery
Microsoft MVP - Visual C++
modified on Saturday, November 15, 2008 1:02 PM
|
|
|
|
|
Thanks Mark, you're great. Didn't expect anyone to do my work - nethertheless you saved my day!
Thank you again, am going to implement this next week!
So long,
eza
PS: Tried to vote for your reply, but it's too far on the right side, and I can't scroll there.
Seems to be a problem of the forum software. Anyway, it's a clear 5 from me!
|
|
|
|
|
No problem! It's a fun exercise. I'm still learning how to
do more complex WPF stuff and this one was a new challenge.
Hopefully you can get something useful out of it. Keeping the
data separate from the UI elements is much nicer and in the spirit
of WPF IMO.
I started another thread here about the Grid.Row/Grid.Column binding.
Learned something new there too
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
FYI
I updated the code I posted above to incorporate the binding code
discussed in the other thread.
The Obs class and the XAML changed.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am using the MVVM pattern, and have a multi-screen data entry form. There is a single VM with an ActiveScreen property that uses INotifyPropertyChanged events. Templates are used by the View based on the current ActiveScreen.
On one of the screens, I have a ComboBox that is bound to a List<> for its ItemsSource. I am using the MVVM pattern, and the selected value of the Combobox is twoway bound to a property on my model. All works fine when you are on the screen entering data.
When the user changes the ActiveScreen, and hence a new template is used in the View, a weird thing happens. The property on the model bound to the combobox is set to NULL. Looking at the call stack, I see the ActiveScreen property change event, then a bunch of WPF code, and then my property setter. The count in the collection on the combobox at that point is 0.
It seems as if WPF does some cleanup of the combobox by removing all the items, which sets the selecteditem to null, and because of my binding, it changes my model. The net effect is I lose the data entered by the user. The other elements on that screen (textboxes, datepickers, etc) do not have this problem, so it's clearly something with the ComboBox.
Has anyone hit this before, and know of a solution? The problem is, I want the user to be able to select a blank value, so I don't know if it's the user setting the value to null or this odd series of events.
|
|
|
|
|
I found this cool plugin that you can use to export your drawings from Adobe Illustrator to XAML...it also works for WPF but you can use it for Silverlight...handy.
XAMLExport[^]
|
|
|
|
|
hi every body
i created silverlight2 application
i put image control which show an image but i want read the image from the web folder
i used this code but it didn`t work with me :
Image i2 = new Image();
i2.Source = new BitmapImage(new Uri("..\\..\\TestWeb\\Images\\session1\\2.jpg", UriKind.Relative));
and:
i2.Source = new BitmapImage(new Uri("../../TestWeb/Images/session1/2.jpg", UriKind.Relative));
any body can tell me how can i do this ???
|
|
|
|
|
|
Here's a simple wrapper around the SHBrowseForFolder() shell function.
*EDIT* Updated with more features!
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace CommonDialogWrappers
{
public class BrowseForFolderDialog
{
#region Public Properties
public string SelectedFolder { get; protected set; }
public string Title
{
get { return BrowseInfo.lpszTitle; }
set { BrowseInfo.lpszTitle = value; }
}
public string InitialFolder { get; set; }
public string InitialExpandedFolder { get; set; }
public string OKButtonText { get; set; }
BROWSEINFOW browseInfo;
public BROWSEINFOW BrowseInfo
{
get { return browseInfo; }
protected set { browseInfo = value; }
}
public BrowseInfoFlags BrowserDialogFlags
{
get { return BrowseInfo.ulFlags; }
set { BrowseInfo.ulFlags = value; }
}
#endregion
#region Public Constructors
public BrowseForFolderDialog()
{
BrowseInfo = new BROWSEINFOW();
BrowseInfo.hwndOwner = IntPtr.Zero;
BrowseInfo.pidlRoot = IntPtr.Zero;
BrowseInfo.pszDisplayName = new String(' ', 260);
BrowseInfo.lpszTitle = "Select a folder:";
BrowseInfo.ulFlags = BrowseInfoFlags.BIF_NEWDIALOGSTYLE;
BrowseInfo.lpfn = new BrowseCallbackProc(BrowseEventHandler);
BrowseInfo.lParam = IntPtr.Zero;
BrowseInfo.iImage = -1;
}
#endregion
#region Public ShowDialog() Overloads
public Nullable<bool> ShowDialog()
{
return PInvokeSHBrowseForFolder(null);
}
public Nullable<bool> ShowDialog(Window owner)
{
return PInvokeSHBrowseForFolder(owner);
}
#endregion
#region PInvoke Stuff
private Nullable<bool> PInvokeSHBrowseForFolder(Window owner)
{
WindowInteropHelper windowhelper;
if (null != owner)
{
windowhelper = new WindowInteropHelper(owner);
BrowseInfo.hwndOwner = windowhelper.Handle;
}
IntPtr pidl = SHBrowseForFolderW(browseInfo);
if (IntPtr.Zero != pidl)
{
StringBuilder pathsb = new StringBuilder(260);
if (false != SHGetPathFromIDList(pidl, pathsb))
{
SelectedFolder = pathsb.ToString();
Marshal.FreeCoTaskMem(pidl);
return true;
}
}
return false;
}
private int BrowseEventHandler(IntPtr hwnd, MessageFromBrowser uMsg, IntPtr lParam, IntPtr lpData)
{
switch (uMsg)
{
case MessageFromBrowser.BFFM_INITIALIZED:
{
if (!string.IsNullOrEmpty(InitialExpandedFolder))
SendMessageW(hwnd, MessageToBrowser.BFFM_SETEXPANDED, new IntPtr(1), InitialExpandedFolder);
else if (!string.IsNullOrEmpty(InitialFolder))
SendMessageW(hwnd, MessageToBrowser.BFFM_SETSELECTIONW, new IntPtr(1), InitialFolder);
if (!string.IsNullOrEmpty(OKButtonText))
SendMessageW(hwnd, MessageToBrowser.BFFM_SETOKTEXT, new IntPtr(1), OKButtonText);
break;
}
case MessageFromBrowser.BFFM_SELCHANGED:
{
StringBuilder pathsb = new StringBuilder(260);
if (false != SHGetPathFromIDList(lParam, pathsb))
{
SelectedFolder = pathsb.ToString();
}
break;
}
case MessageFromBrowser.BFFM_VALIDATEFAILEDA:
{
break;
}
case MessageFromBrowser.BFFM_VALIDATEFAILEDW:
{
break;
}
case MessageFromBrowser.BFFM_IUNKNOWN:
{
break;
}
}
return 0;
}
public delegate int BrowseCallbackProc(IntPtr hwnd, MessageFromBrowser uMsg, IntPtr lParam, IntPtr lpData);
[Flags]
public enum BrowseInfoFlags : uint
{
BIF_None = 0x0000,
BIF_RETURNONLYFSDIRS = 0x0001,
BIF_DONTGOBELOWDOMAIN = 0x0002,
BIF_STATUSTEXT = 0x0004,
BIF_RETURNFSANCESTORS = 0x0008,
BIF_EDITBOX = 0x0010,
BIF_VALIDATE = 0x0020,
BIF_NEWDIALOGSTYLE = 0x0040,
BIF_USENEWUI = BIF_NEWDIALOGSTYLE | BIF_EDITBOX,
BIF_BROWSEINCLUDEURLS = 0x0080,
BIF_UAHINT = 0x0100,
BIF_NONEWFOLDERBUTTON = 0x0200,
BIF_NOTRANSLATETARGETS = 0x0400,
BIF_BROWSEFORCOMPUTER = 0x1000,
BIF_BROWSEFORPRINTER = 0x2000,
BIF_BROWSEINCLUDEFILES = 0x4000,
BIF_SHAREABLE = 0x8000
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class BROWSEINFOW
{
public IntPtr hwndOwner;
public IntPtr pidlRoot;
public string pszDisplayName;
public string lpszTitle;
public BrowseInfoFlags ulFlags;
public BrowseCallbackProc lpfn;
public IntPtr lParam;
public int iImage;
}
public enum MessageFromBrowser : uint
{
BFFM_INITIALIZED = 1,
BFFM_SELCHANGED = 2,
BFFM_VALIDATEFAILEDA = 3,
BFFM_VALIDATEFAILEDW = 4,
BFFM_IUNKNOWN = 5
}
public enum MessageToBrowser : uint
{
WM_USER = 0x0400,
BFFM_SETSTATUSTEXTA = WM_USER + 100,
BFFM_ENABLEOK = WM_USER + 101,
BFFM_SETSELECTIONA = WM_USER + 102,
BFFM_SETSELECTIONW = WM_USER + 103,
BFFM_SETSTATUSTEXTW = WM_USER + 104,
BFFM_SETOKTEXT = WM_USER + 105,
BFFM_SETEXPANDED = WM_USER + 106
}
[DllImport("shell32.dll")]
private static extern IntPtr SHBrowseForFolderW([MarshalAs(UnmanagedType.LPStruct), In, Out] BROWSEINFOW bi);
[DllImport("shell32.dll")]
private static extern bool SHGetPathFromIDList(IntPtr pidl, StringBuilder path);
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, MessageToBrowser msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string str);
#endregion
}
}
Sample usage:
CommonDialogWrappers.BrowseForFolderDialog dlg = new CommonDialogWrappers.BrowseForFolderDialog();
dlg.Title = "Select a folder and click OK!";
dlg.InitialExpandedFolder = @"c:\";
dlg.OKButtonText = "OK!";
if (true == dlg.ShowDialog(this))
{
MessageBox.Show(dlg.SelectedFolder, "Selected Folder");
}
Mark Salsbery
Microsoft MVP - Visual C++
modified on Wednesday, November 12, 2008 2:48 PM
|
|
|
|
|
Nicely done there sir. Nice code....
|
|
|
|
|
Heh thanks.
I think the only comments are the ones copied from SDK headers.
I matched the ShowDialog prototypes to Microsoft.Win32.OpenFileDialog's
ShowDialog() methods, hence the Nullable<bool> return type.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
Thanks!
I updated the post to include all the features of the common dialog
(and <summary> info ripped from the SDK;.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi!
I have defined a simple template to use on all windows of an application. At the beginning I wrote the style as a window resource, as shown below:
<Window.Resources>
<DataTemplate x:Key="gridDelete">
<Border Padding="2">
<Button x:Name="imgDelete" Click="imgDelete_Click" Background="Transparent" Cursor="Hand"/>
</Border>
</DataTemplate>
</Window.Resources>
In order to avoid copying this template on all the windows, I moved it to an application resource, but then I keep receiving errors stating that the imgDelete_Click can't be found. How can I define an application level template like this, and add events to the button only on the windows?
Best regards,
rferj
|
|
|
|
|
|
Hi,
In my client application (WPF) I am trying to upload a document to a sharepoint site by using WCF web service. I am able to upload documents to site upto 35 Kb. If I try to upload a file more than 35 kb in size then it throws following error message while uploading the file.
The remote server returned an unexpected response:(400) Bad Request
I have added following <binding> tag in web.config file of my WCF service
<bindings>
<wsHttpBinding>
<binding name="wshttpconfig">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
</binding>
after this I did set bindingConfiguration="wshttpconfig" in <endpoint tag>
<endpoint bindingConfiguration="wshttpconfig".....
But I still encounter the same problem.
Do I need to make any other settings in the app.config file of WCF Service
application?
Regards,
Vipul Mehta
|
|
|
|
|
Hi all.
I've created a storyboard, now I wanna run a method in secondary second of it ? means I wanna figure out when the animation reaches to the secondary second.
How can I do it ?
|
|
|
|
|