|
If you want to know what version of Office have your client installed you can try this:
Code Project Article
Regards
Christian Amado
MCITP | MCTS | MOS | MTA
DCE 0★ 1★ 2★ 3★ 4★ 5★
Bronze level MVA
Olimpia ☆ ★★★
|
|
|
|
|
Hi Christian.
This Topic get only one version.
I want get another version.
Thank bro!
|
|
|
|
|
The exact code of this only gets one version, however looking through the registry it looks like you can figure that out, consider "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\" which contains sub keys for each installed version of office.
If or how registry access works in silverlight i'm not sure, but if the only problem with the provided sample is just one version being returned then you can get that info from the registry.
|
|
|
|
|
Let me clarify that a bit more. I'm currently binding my buttons to be enabled if my Stored settings bool value is true. Meaning in this case dbOpen. This is true if my database is loaded, false if it's closed. Now I have certain buttons I want to be enabled when this is true so I have the xml code like this:
IsEnabled="{Binding Source={x:Static prop:Settings.Default}, Path=dbOpen, Mode=TwoWay}"
Now I want certain buttons to be able to be disabled when the dbOpen is true so how do I flip the value in the xml statement? in c# it would be like :
If (Settings.Default.dbOpen) to check if it's not true you would If(!Settings.Default.dbopen)
modified 24-Jul-12 11:04am.
|
|
|
|
|
I have a set of NOT converters!
public class BooleanNotConverter : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool bReturn = false;
int iValue;
try
{
if (Int32.TryParse(value.ToString(), out iValue))
{
bReturn = iValue != 0;
}
else
{
Boolean.TryParse(value.ToString(), out bReturn);
}
}
catch { bReturn = false; }
return !bReturn;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
int iReturn = 0;
bool bReturn = false;
Boolean.TryParse(value.ToString(), out bReturn);
if (!bReturn)
{ iReturn = -1; }
return iReturn;
}
}
And the xaml
IsEnabled="{Binding IsLocked,Converter={StaticResource BooleanNotConverter}}"
And the App.xaml resource
<!--Converter Resource-->
<ResourceDictionary>
<converter:BooleanNotConverter x:Key="BooleanNotConverter"/>
</ResourceDictionary>
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
For some reason it's just not working as expected. The open database button is enabled by default this allows it to open a database. Once I load the database I set the dbOpen property to True which if this is working properly should disable the button since it inverts the True to a false. But it's not. The Button is enabled the entire time. Now I know dbOpen is true because my code to load the database will only run if(!System.Properties.Default.dbOpen), and while the button does not disable the code to open the database does not fire when clicked.
|
|
|
|
|
I know this is a really dumb suggestion but try it any way, presuming your converter is working as expected and have tested it on some other control, try changing your button from a Command"" to Click. I have found (twice) that for some reason the IsEnabled event is ignored if there is a command on the button (I have no idea why and don't have the motivation to chase it down as it happens only rarely).
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I tried that and sadly it didn't change anything. One thing is possible I'm using the Actipro WPF Ribbon and it's the QAT open button, and backstage open buttons I'm trying to disable using this method. I don't know if by chance it's an issue with their control or not.
I can tell you that I have had success using a regular boolean converter to enable/disable the buttons on their ribbon, just not this inverted boolean converter.
|
|
|
|
|
Got it working!
Was a really stupid mistake I forgot to tell it the source of where my variable to tie it too was. Since it's a Property stored by the project I had to do the IsEnabled command as so:
IsEnabled="{Binding Source={x:Static prop:Settings.Default}, Path=dbOpen, Converter={StaticResource booleanNotConverter}}"
|
|
|
|
|
While your code works just fine... a more generic solution is to use a map converter. That way you don't need to keep writing these one-off converters that basically map one value to another. It's all in one converter and you just define the mapping in XAML.
|
|
|
|
|
Well don't just drop it as a comment, link please. I have about 8 converters so there is very limited rewriting.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
. Ok...
It's part of this project: http://wpfconverters.codeplex.com/[^]
Like I said, nothing wrong with your code. Just that this converter allowed me to get rid of about 73 others. You can map any value you can reference in XAML to any other value.
I use it for bool inversion... I also use it in a clever way to allow for triggering on empty collections. I map count=0 to true and then use the fallback value (for any other count) = false.
|
|
|
|
|
Thanks for that, something for the weekend experimentation!
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Still trying to grasp MVVM here. I have 4 controls I display from my main form.
Basically
<DockPanel LastChildFill="True">
<views:RibbonControl x:Name="mainRibbon" DockPanel.Dock="Top" />
<controls:StatusBarControl x:Name="mainStatusBar" DockPanel.Dock="Bottom" />
<controls:NavigationControl x:Name="mainNavigation"
DockPanel.Dock="Left"
Visibility="Hidden" />
<controls:DisplayContactsControl x:Name="mainContactsDisplay"
DockPanel.Dock="Left"
Visibility="Hidden" />
</DockPanel>
How can I update say messages for the status bar when things occur inside one of the other controls. Lets say On the RibbonControl there is a button to open the database. The code to open it would include references to displaying a message on the statusbar control that the form is loading and also update the title of the form to display the path of the database, name and title of the application. Now I can do this in regular WPF but their is code behind I'm trying to understand how to do this in MVVM.
modified 24-Jul-12 11:05am.
|
|
|
|
|
Most people doing this would use either a Messenger or a Mediator. These are common techniques that play nicely with MVVM.
|
|
|
|
|
Using Binding on your StatusBarControl will helps you.
Christian Amado
MCITP | MCTS | MOS | MTA
DCE 0★ 1★ 2★ 3★ 4★ 5★
Bronze level MVA
Olimpia ☆ ★★★
|
|
|
|
|
I'm not sure I understand. How would binding allow me to display something like, Management Mode - Contacts Manager - Editing Contacts? Or Management Mode - Contacts Manager - Create New Contact?
|
|
|
|
|
Bind the controls text property to a property (VMProp) in your VM, update VMProp with the status you need to display. That update is driven by the processes in the VM that are initiate by the user.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I think I understand. I've noticed that MVVM is basically Bind everything lol.
|
|
|
|
|
Alisaunder wrote: MVVM is basically Bind everything
You have that absolutely correct. No more code to manipulate the UI directly, everything is in the VM, or converters etc
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Unless the OP is using a single VM, you have missed important information out. How is another unrelated control going to be updated? If you see my answer, you can see the common mechanisms which answers the question the OP actually asked.
|
|
|
|
|
I'm trying to add images to a column in a WPF datagrid which are read from a folder and not added as a static resource. The datagrid shows the path to the image in debug but the cell is empty.
XAML:
<DataGrid
Name="dgDevices"
AutoGenerateColumns="False"
CanUserAddRows="False"
ItemsSource="{Binding Scanners}"
SelectionChanged="dgDevices_SelectionChanged">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Device Image">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Name="imgScanner" Source="{Binding Path=ImageFile}" Height="100" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Details" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap">
<TextBlock Text="{Binding Path=FriendlyName}"/>
<Hyperlink NavigateUri="{Binding Path=URL}" RequestNavigate="Hyperlink_RequestNavigate">
<TextBlock Text="{Binding Path=URL}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Code that describes the objects for the datagrid:
public class Scanners : INotifyPropertyChanged
{
#region dongleNum related info
private UInt32 thisIPAddress;
public UInt32 IPAddress
{
get { return thisIPAddress; }
set { thisIPAddress = value; NotifyPropertyChanged("IPAddress"); }
}
private UInt64 thisMACAddress;
public UInt64 MACAddress
{
get { return thisMACAddress; }
set { thisMACAddress = value; NotifyPropertyChanged("MACAddress"); }
}
#endregion
#region Device related info
private string thisPortName;
public string PortName
{
get { return thisPortName; }
set { thisPortName = value; NotifyPropertyChanged("PortName"); }
}
#endregion
#region Driver related info
private string thisDeviceGuid;
public string DeviceGuid
{
get { return thisDeviceGuid; }
set { thisDeviceGuid = value; NotifyPropertyChanged("DeviceGuid"); }
}
#endregion
#region Presentation related info
private string thisImageFile;
public string ImageFile
{
get { return thisImageFile; }
set { thisImageFile = value; NotifyPropertyChanged("ImageFile"); }
}
private string thisFriendlyName;
public string FriendlyName
{
get { return thisFriendlyName; }
set { thisFriendlyName = value; NotifyPropertyChanged("FriendlyName"); }
}
private Uri thisURL;
public Uri URL
{
get { return thisURL; }
set { thisURL = value; NotifyPropertyChanged("URL"); }
}
#endregion
#region Constructors
public Scanners(string newFriendlyName, string newImageFile)
{
FriendlyName = newFriendlyName;
ImageFile = newImageFile;
}
public Scanners(sxWrapper.sxDeviceInfo DeviceInfo, string newFriendlyName, Uri newURL, string newImageFile, string newDeviceGuid)
{
MACAddress = DeviceInfo.MACAddress;
IPAddress = DeviceInfo.IPAddress;
PortName = DeviceInfo.PortName;
FriendlyName = newFriendlyName;
URL = newURL;
ImageFile = newImageFile;
DeviceGuid = newDeviceGuid;
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Private Helpers
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
public class DeviceViewModel
{
private static ObservableCollection<Scanners> devices = null;
public static ObservableCollection<Scanners> Devices
{
get { return devices; }
set { devices = value; }
}
public DeviceViewModel()
{
this.Initialize();
}
private void Initialize()
{
Reset();
}
public static void Reset()
{
devices = new ObservableCollection<Scanners>();
}
public static void Add(Scanners Scanner)
{
devices.Add(Scanner);
}
}
The Path "ImageFile" in the XAML is a string which is the image's location. i.e. "Images\image1.bmp" The folder Images is located in the target folder containing bmp images. I can only display images in the cells if the images are added as resources in the project. I read a string from an INI class that describes the file name in the Images folder. There are other strings read from the INI file that appear in the other column. Only the images don't appear.
I don't what I am doing wrong, please help.
|
|
|
|
|
Try this (works on Silverlight too):
Create a converter class:
public sealed class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
return new BitmapImage(new Uri((string)value));
}
catch
{
return new BitmapImage();
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your XAML you must add a new resource and implement a convert in your image element inside the CellTemplate. Remember to add the extension namespace on your xaml file header.
<DataGrid
Name="dgDevices"
AutoGenerateColumns="False"
CanUserAddRows="False"
ItemsSource="{Binding Scanners}" SelectionChanged="dgDevices_SelectionChanged"> <DataGrid.Resources>
<extension:ImageConverter x:key="imgConverter" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Device Image">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Name="imgScanner" Source="{Binding Path=ImageFile,
Converter={StaticResource imgConverter}}" }" Height="100" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Details" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap">
<TextBlock Text="{Binding Path=FriendlyName}"/>
<Hyperlink NavigateUri="{Binding Path=URL}" RequestNavigate="Hyperlink_RequestNavigate">
<TextBlock Text="{Binding Path=URL}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Hope its helps
Christian Amado
MCITP | MCTS | MOS | MTA
DCE 0★ 1★ 2★ 3★ 4★ 5★
Bronze level MVA
Olimpia ☆ ★★★
|
|
|
|
|
I found the following as a source of help towards the solution:
public class ImageConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return new BitmapImage(new Uri((string)value, UriKind.RelativeOrAbsolute));
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
The path to the image is Images\File.bmp. I tried changing the formatting of the string to create a proper Uri, but the image STILL does not appear in the cell
I found a solution which helped in better creating the path to be in the proper form of a Uri. What follows IS the solution:
public class ImageConverter : IValueConverter
{
public static BitmapImage CreateBMImage(string path)
{
BitmapImage bi = new BitmapImage();
try
{
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnDemand;
Uri baseUri = new Uri(Application.ResourceAssembly.Location);
bi.UriSource = new Uri(baseUri, path);
bi.EndInit();
}
catch
{
return null;
}
return bi;
}
public static Image CreateImage(string path)
{
Image img = new Image();
img.Source = CreateBMImage(path);
return img;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
return CreateBMImage((string)value);
}
catch
{
return new BitmapImage();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
modified 23-Jul-12 10:34am.
|
|
|
|
|
The subject is somewhat of a misnomer, I have a category combobox that governs what defects are available, but that is it. The category information should not be saved. Easier to show than say:
Here is the relevant ViewModel:
public Category SelectedCategory
{
get { return _selectedCategory; }
set
{
if (value == null) return;
_selectedCategory = value;
OnPropertyChanged("SelectedCategory");
LoadDefects(_selectedCategory.id);
}
}
And the View:
<ComboBox
Grid.Row="2"
Grid.Column="1"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.AllCategories}"
DisplayMemberPath="name"
SelectedValuePath="id"
SelectedValue="{Binding SelectedItem.Defect.categoryId}"
SelectedItem="{Binding SelectedCategory}" />
<ComboBox
Grid.Row="3"
Grid.Column="1"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.AllDefects}"
DisplayMemberPath="name"
SelectedValuePath="id"
SelectedValue="{Binding SelectedItem.defectId}"/>
What is happening is that instead of just saving the SelectedItem (Observation class not shown) it is changing SelectedItem.Defect.CategoryId, which I don't want. I only want SelectedItem to be saved. Save routine is pretty simple:
ViewModel:
private void Save()
{
_con.SaveChanges();
}
Thoughts?
Cheers, --EA
|
|
|
|