/Application/GUI/Windows/PropertiesWindow.xaml.cs

http://yet-another-music-application.googlecode.com/ · C# · 765 lines · 472 code · 104 blank · 189 comment · 78 complexity · 33fb5768e9d45c1d3851edd14cb236a7 MD5 · raw file

  1. /**
  2. * PropertiesWindow.xaml.cs
  3. *
  4. * The dialog showing information about one or several
  5. * tracks.
  6. *
  7. * * * * * * * * *
  8. *
  9. * This code is part of the Stoffi Music Player Project.
  10. * Visit our website at: stoffiplayer.com
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version
  15. * 3 of the License, or (at your option) any later version.
  16. *
  17. * See stoffiplayer.com/license for more information.
  18. **/
  19. using System;
  20. using System.Collections.Generic;
  21. using System.Collections.ObjectModel;
  22. using System.IO;
  23. using System.Linq;
  24. using System.Text;
  25. using System.Windows;
  26. using System.Windows.Controls;
  27. using System.Windows.Data;
  28. using System.Windows.Documents;
  29. using System.Windows.Input;
  30. using System.Windows.Media;
  31. using System.Windows.Media.Imaging;
  32. namespace Stoffi
  33. {
  34. /// <summary>
  35. /// Interaction logic for PropertiesWindow.xaml
  36. /// </summary>
  37. public partial class PropertiesWindow : Window
  38. {
  39. #region Members
  40. /// <summary>
  41. /// Used to hold the data before writing it to file
  42. /// </summary>
  43. private TrackData tempTrack = new TrackData();
  44. /// <summary>
  45. /// Holds the list of all properties inside DetailsList
  46. /// </summary>
  47. ObservableCollection<PropertyData> properties = new ObservableCollection<PropertyData>();
  48. #endregion
  49. #region Properties
  50. /// <summary>
  51. /// Gets the tracks that are being viewed
  52. /// </summary>
  53. public List<TrackData> Tracks { get; private set; }
  54. #endregion
  55. #region Constructor
  56. /// <summary>
  57. /// Creates an instance of the PropertiesWindow window.
  58. /// </summary>
  59. /// <param name="tracks">The tracks to load</param>
  60. public PropertiesWindow(List<TrackData> tracks)
  61. {
  62. U.L(LogLevel.Debug, "PROPERTIES", "Initialize");
  63. InitializeComponent();
  64. U.L(LogLevel.Debug, "PROPERTIES", "Initialized");
  65. int size = 16;
  66. PrevImage.Source = Utilities.GetIcoImage("pack://application:,,,/GUI/Images/Icons/LeftArrow.ico", size, size);
  67. NextImage.Source = Utilities.GetIcoImage("pack://application:,,,/GUI/Images/Icons/RightArrow.ico", size, size);
  68. PrevImage.Height = size;
  69. NextImage.Height = size;
  70. PrevImage.Width = size;
  71. NextImage.Width = size;
  72. OK.Visibility = System.Windows.Visibility.Collapsed;
  73. Apply.Visibility = System.Windows.Visibility.Collapsed;
  74. Cancel.Content = U.T("ButtonClose", "Content");
  75. Tracks = new List<TrackData>();
  76. AddTracks(tracks);
  77. if (System.Windows.Forms.VisualStyles.VisualStyleInformation.DisplayName != "")
  78. {
  79. Tabs.Background = Brushes.White;
  80. Background = Brushes.WhiteSmoke;
  81. }
  82. }
  83. #endregion
  84. #region Methods
  85. #region Public
  86. /// <summary>
  87. /// Loads a number of tracks into the window
  88. /// </summary>
  89. /// <param name="tracksToAdd">The tracks to load</param>
  90. public void AddTracks(List<TrackData> tracksToAdd)
  91. {
  92. Tracks.Clear();
  93. Tracks.AddRange(tracksToAdd);
  94. if (Tracks.Count == 1)
  95. {
  96. // load values
  97. string p = Tracks[0].Path;
  98. string e = Path.GetExtension(p).Substring(1);
  99. FileInfo fInfo = new FileInfo(p);
  100. TagLib.File file = TagLib.File.Create(p, TagLib.ReadStyle.Average);
  101. // set temp track
  102. tempTrack.Path = p;
  103. // set visibilities
  104. LastPlayed.Visibility = System.Windows.Visibility.Visible;
  105. CreatedAt.Visibility = System.Windows.Visibility.Visible;
  106. ModifiedAt.Visibility = System.Windows.Visibility.Visible;
  107. AccessedAt.Visibility = System.Windows.Visibility.Visible;
  108. LastPlayedLabel.Visibility = System.Windows.Visibility.Visible;
  109. CreatedAtLabel.Visibility = System.Windows.Visibility.Visible;
  110. ModifiedAtLabel.Visibility = System.Windows.Visibility.Visible;
  111. AccessedAtLabel.Visibility = System.Windows.Visibility.Visible;
  112. Filename.Visibility = System.Windows.Visibility.Visible;
  113. Filecount.Visibility = System.Windows.Visibility.Collapsed;
  114. ArtBackgroundMultiple.Visibility = System.Windows.Visibility.Collapsed;
  115. ArtBackgroundSingle.Visibility = System.Windows.Visibility.Collapsed;
  116. // set textblocks
  117. Filename.Text = Path.GetFileName(p);
  118. Filetype.Text = String.Format(U.T("PropertiesGeneralTypeFormat"), e.ToUpper(), e);
  119. Filepath.Text = Path.GetDirectoryName(p);
  120. Filesize.Text = U.HumanSize(fInfo.Length);
  121. Codec.Text = Tracks[0].Codecs;
  122. Bitrate.Text = Tracks[0].Bitrate.ToString();
  123. Channels.Text = Tracks[0].Channels.ToString();
  124. LastPlayed.Text = Tracks[0].LastPlayed;
  125. Length.Text = Tracks[0].Length;
  126. PlayCount.Text = Tracks[0].PlayCount.ToString();
  127. SampleRate.Text = Tracks[0].SampleRate.ToString();
  128. CreatedAt.Text = fInfo.CreationTime.ToString();
  129. ModifiedAt.Text = fInfo.LastWriteTime.ToString();
  130. AccessedAt.Text = fInfo.LastAccessTime.ToString();
  131. // set art
  132. AlbumArt.Source = FilesystemManager.GetImageTag(Tracks[0]);
  133. }
  134. else if (Tracks.Count > 1)
  135. {
  136. Filename.Visibility = System.Windows.Visibility.Collapsed;
  137. Filecount.Visibility = System.Windows.Visibility.Visible;
  138. LastPlayed.Visibility = System.Windows.Visibility.Collapsed;
  139. CreatedAt.Visibility = System.Windows.Visibility.Collapsed;
  140. ModifiedAt.Visibility = System.Windows.Visibility.Collapsed;
  141. AccessedAt.Visibility = System.Windows.Visibility.Collapsed;
  142. LastPlayedLabel.Visibility = System.Windows.Visibility.Collapsed;
  143. CreatedAtLabel.Visibility = System.Windows.Visibility.Collapsed;
  144. ModifiedAtLabel.Visibility = System.Windows.Visibility.Collapsed;
  145. AccessedAtLabel.Visibility = System.Windows.Visibility.Collapsed;
  146. TrackData t = Tracks[0];
  147. string e = Path.GetExtension(t.Path).Substring(1);
  148. string location = Path.GetDirectoryName(t.Path);
  149. long size = 0;
  150. string bitrate = t.Bitrate.ToString();
  151. string channels = t.Channels.ToString();
  152. double length = 0;
  153. uint playcount = 0;
  154. string samplerate = t.SampleRate.ToString();
  155. string codec = t.Codecs;
  156. foreach (TrackData track in Tracks)
  157. {
  158. FileInfo f = new FileInfo(track.Path);
  159. size += f.Length;
  160. length += track.RawLength;
  161. playcount += track.PlayCount;
  162. if (Path.GetExtension(track.Path).Substring(1) != e)
  163. e = U.T("PropertiesGeneralVariousFormats");
  164. if (Path.GetDirectoryName(t.Path) != location)
  165. location = U.T("PropertiesGeneralVariousLocations");
  166. if (track.Bitrate.ToString() != bitrate)
  167. bitrate = U.T("PropertiesGeneralVariousBitrates");
  168. if (track.Channels.ToString() != channels)
  169. channels = U.T("PropertiesGeneralVariousChannels");
  170. if (track.SampleRate.ToString() != samplerate)
  171. samplerate = U.T("PropertiesGeneralVariousSamplerates");
  172. if (track.Codecs.ToString() != codec)
  173. codec = U.T("PropertiesGeneralVariousCodecs");
  174. }
  175. if (e != U.T("PropertiesGeneralVariousFormats"))
  176. Filetype.Text = String.Format(U.T("PropertiesGeneralTypeFormat"), e.ToUpper(), e);
  177. else
  178. Filetype.Text = e;
  179. Filecount.Text = String.Format(U.T("PropertiesMultipleFiles"), Tracks.Count);
  180. Filepath.Text = location;
  181. Filesize.Text = U.HumanSize(size);
  182. Codec.Text = codec;
  183. Bitrate.Text = bitrate;
  184. Channels.Text = channels;
  185. Length.Text = U.TimeSpanToString(new TimeSpan(0, 0, Convert.ToInt32(length)));
  186. PlayCount.Text = playcount.ToString();
  187. SampleRate.Text = samplerate;
  188. AlbumArt.Source = FilesystemManager.GetImageTag(Tracks[0]);
  189. ArtBackgroundMultiple.Visibility = System.Windows.Visibility.Collapsed;
  190. ArtBackgroundSingle.Visibility = System.Windows.Visibility.Collapsed;
  191. }
  192. FillProperties();
  193. }
  194. #endregion
  195. #region Private
  196. /// <summary>
  197. /// Checks if two strings are equal.
  198. /// An empty string and null are considered equal.
  199. /// </summary>
  200. /// <param name="str1">The first string</param>
  201. /// <param name="str2">The second string</param>
  202. /// <returns>True if the strings are equal, otherwise false</returns>
  203. private bool FieldsEqual(string str1, string str2)
  204. {
  205. return (str1 == str2 || (str1 == "" && str2 == null) || (str2 == "" && str1 == null));
  206. }
  207. /// <summary>
  208. /// Gets the value of a specific metadata tag given its name
  209. /// </summary>
  210. /// <param name="track">The track to retrieve the tag from</param>
  211. /// <param name="tag">The name of the tag</param>
  212. /// <returns>The value of the tag</returns>
  213. private object GetTag(TrackData track, string tag)
  214. {
  215. switch (tag)
  216. {
  217. case "Artist":
  218. return track.Artist as object;
  219. case "Title":
  220. return track.Title as object;
  221. case "Album":
  222. return track.Album as object;
  223. case "Genre":
  224. return track.Genre as object;
  225. case "Track":
  226. return track.Track as object;
  227. case "Year":
  228. if (track.Year == null)
  229. return null;
  230. object y = track.Year as object;
  231. return track.Year as object;
  232. default:
  233. return "" as object;
  234. }
  235. }
  236. /// <summary>
  237. /// Gets the property given its name
  238. /// </summary>
  239. /// <param name="name">The name of the property</param>
  240. /// <returns>The PropertyData in properties with the name <paramref name="name"/>.
  241. /// null if none found.</returns>
  242. private PropertyData GetProperty(string name)
  243. {
  244. foreach (PropertyData p in properties)
  245. if (name == p.Name)
  246. return p;
  247. return null;
  248. }
  249. /// <summary>
  250. /// Gets the property value given its name
  251. /// </summary>
  252. /// <param name="name">The name of the property</param>
  253. /// <returns>The value of the PropertyData in properties with the name <paramref name="name"/>.
  254. /// null if none found.</returns>
  255. private string GetPropertyValue(string name)
  256. {
  257. foreach (PropertyData p in properties)
  258. if (name == p.Name)
  259. return p.Value;
  260. return null;
  261. }
  262. /// <summary>
  263. /// Checks if the tracks have the same value for a given tag
  264. /// </summary>
  265. /// <param name="tag">The name of the metadata tag</param>
  266. /// <returns>Either the string for all tracks value of the field,
  267. /// or a string describing that the values are different</returns>
  268. private string CheckIfSame(string tag)
  269. {
  270. if (Tracks.Count < 1) return null;
  271. bool same = true;
  272. object o = GetTag(Tracks[0], tag);
  273. foreach (TrackData t in Tracks)
  274. {
  275. object p = GetTag(t, tag);
  276. if ((o != p && o == null) || (o.ToString() != p.ToString()))
  277. {
  278. same = false;
  279. break;
  280. }
  281. }
  282. string s = o == null ? "" : o.ToString();
  283. return same ? s : U.T("PropertiesDetailsMultipleValues");
  284. }
  285. /// <summary>
  286. /// Loads data into DetailsList
  287. /// </summary>
  288. private void FillProperties()
  289. {
  290. string title = "";
  291. string artist = "";
  292. string album = "";
  293. string year = "";
  294. string track = "";
  295. string genre = "";
  296. if (Tracks.Count == 1)
  297. {
  298. title = Tracks[0].Title;
  299. artist = Tracks[0].Artist;
  300. album = Tracks[0].Album;
  301. year = Tracks[0].Year.ToString();
  302. track = Tracks[0].Track.ToString();
  303. genre = Tracks[0].Genre;
  304. }
  305. else
  306. {
  307. title = CheckIfSame("Title");
  308. artist = CheckIfSame("Artist");
  309. album = CheckIfSame("Album");
  310. year = CheckIfSame("Year");
  311. track = CheckIfSame("Track");
  312. genre = CheckIfSame("Genre");
  313. }
  314. properties.Clear();
  315. properties.Add(new PropertyData() { Edited = false, Name = U.T("ColumnTitle"), Value = title });
  316. properties.Add(new PropertyData() { Edited = false, Name = U.T("ColumnArtist"), Value = artist });
  317. properties.Add(new PropertyData() { Edited = false, Name = U.T("ColumnAlbum"), Value = album });
  318. properties.Add(new PropertyData() { Edited = false, Name = U.T("ColumnYear"), Value = year as string });
  319. properties.Add(new PropertyData() { Edited = false, Name = U.T("ColumnTrack"), Value = track as string });
  320. properties.Add(new PropertyData() { Edited = false, Name = U.T("ColumnGenre"), Value = genre });
  321. DetailsList.ItemsSource = properties;
  322. // load into temporary holder
  323. tempTrack.Title = title;
  324. tempTrack.Artist = artist;
  325. tempTrack.Album = album;
  326. if (track != U.T("PropertiesDetailsMultipleValues") && track != "")
  327. tempTrack.Track = Convert.ToUInt32(track);
  328. if (year != U.T("PropertiesDetailsMultipleValues") && year != "")
  329. tempTrack.Year = Convert.ToUInt32(year);
  330. tempTrack.Genre = genre;
  331. }
  332. /// <summary>
  333. /// Saves data from DetailsList into tempTrack
  334. /// </summary>
  335. private void SaveProperties()
  336. {
  337. foreach (PropertyData p in properties)
  338. {
  339. if (p.Edited)
  340. switch (p.Name)
  341. {
  342. case "Artist":
  343. tempTrack.Artist = p.Value;
  344. break;
  345. case "Title":
  346. tempTrack.Title = p.Value;
  347. break;
  348. case "Album":
  349. tempTrack.Album = p.Value;
  350. break;
  351. case "Genre":
  352. tempTrack.Genre = p.Value;
  353. break;
  354. case "Track":
  355. try
  356. {
  357. tempTrack.Track = Convert.ToUInt32(p.Value);
  358. }
  359. catch (Exception e)
  360. {
  361. MessageBox.Show(e.Message, "Could Not Save Value", MessageBoxButton.OK, MessageBoxImage.Error);
  362. }
  363. break;
  364. case "Year":
  365. try
  366. {
  367. tempTrack.Year = Convert.ToUInt32(p.Value);
  368. }
  369. catch (Exception e)
  370. {
  371. MessageBox.Show(e.Message, "Could Not Save Value", MessageBoxButton.OK, MessageBoxImage.Error);
  372. }
  373. break;
  374. }
  375. p.Edited = false;
  376. }
  377. }
  378. /// <summary>
  379. /// Saves all data of tempTrack to the tracks
  380. /// </summary>
  381. private void Save()
  382. {
  383. SaveProperties();
  384. foreach (TrackData t in Tracks)
  385. {
  386. t.Title = tempTrack.Title;
  387. t.Artist = tempTrack.Artist;
  388. t.Album = tempTrack.Album;
  389. t.Genre = tempTrack.Genre;
  390. t.Track = tempTrack.Track;
  391. try
  392. {
  393. FilesystemManager.SaveTrack(t);
  394. }
  395. catch (Exception e)
  396. {
  397. MessageBox.Show(e.Message, U.T("MessageErrorUpdating", "Title"), MessageBoxButton.OK, MessageBoxImage.Error);
  398. }
  399. }
  400. if (Tracks.Count == 1)
  401. {
  402. string oldPath = Tracks[0].Path;
  403. string newPath = Path.Combine(Path.GetDirectoryName(oldPath), Filename.Text);
  404. if (oldPath != newPath)
  405. {
  406. try
  407. {
  408. File.Move(oldPath, newPath);
  409. tempTrack.Path = newPath;
  410. }
  411. catch (Exception e)
  412. {
  413. MessageBox.Show(e.Message, U.T("MessageErrorRenaming", "Title"), MessageBoxButton.OK, MessageBoxImage.Error);
  414. }
  415. }
  416. }
  417. ToggleButtons();
  418. }
  419. /// <summary>
  420. /// Will show a set of buttons depending on
  421. /// whether any value has changed.
  422. ///
  423. /// changed:
  424. /// OK, Cancel, Apply
  425. ///
  426. /// not changed:
  427. /// Close
  428. /// </summary>
  429. private void ToggleButtons()
  430. {
  431. bool anyChanged = false;
  432. // check properties
  433. foreach (PropertyData p in properties)
  434. {
  435. if (p.Edited)
  436. {
  437. anyChanged = true;
  438. break;
  439. }
  440. }
  441. // check filename
  442. string filename = Path.GetFileName(tempTrack.Path);
  443. if (Tracks.Count == 1 && filename != Filename.Text)
  444. anyChanged = true;
  445. if (anyChanged)
  446. {
  447. OK.Visibility = System.Windows.Visibility.Visible;
  448. Apply.Visibility = System.Windows.Visibility.Visible;
  449. Cancel.Content = U.T("ButtonCancel", "Content");
  450. }
  451. else
  452. {
  453. OK.Visibility = System.Windows.Visibility.Collapsed;
  454. Apply.Visibility = System.Windows.Visibility.Collapsed;
  455. Cancel.Content = U.T("ButtonClose", "Content");
  456. }
  457. }
  458. #endregion
  459. #region Event handlers
  460. /// <summary>
  461. /// Invoked when the user clicks "Next"
  462. /// </summary>
  463. /// <param name="sender">The sender of the event</param>
  464. /// <param name="e">The event data</param>
  465. /// <remarks>Will load the next track</remarks>
  466. private void Next_Click(object sender, RoutedEventArgs e)
  467. {
  468. OnNext();
  469. }
  470. /// <summary>
  471. /// Invoked when the user clicks "Previous"
  472. /// </summary>
  473. /// <param name="sender">The sender of the event</param>
  474. /// <param name="e">The event data</param>
  475. /// <remarks>Will load the previous track</remarks>
  476. private void Previous_Click(object sender, RoutedEventArgs e)
  477. {
  478. OnPrev();
  479. }
  480. /// <summary>
  481. /// Invoked when the user clicks "OK"
  482. /// </summary>
  483. /// <param name="sender">The sender of the event</param>
  484. /// <param name="e">The event data</param>
  485. /// <remarks>Will close the window after saving</remarks>
  486. private void OK_Click(object sender, RoutedEventArgs e)
  487. {
  488. Save();
  489. Close();
  490. }
  491. /// <summary>
  492. /// Invoked when the user clicks "Apply"
  493. /// </summary>
  494. /// <param name="sender">The sender of the event</param>
  495. /// <param name="e">The event data</param>
  496. /// <remarks>Will save all data</remarks>
  497. private void Apply_Click(object sender, RoutedEventArgs e)
  498. {
  499. Save();
  500. }
  501. /// <summary>
  502. /// Invoked when the user clicks "Close" or "Cancel"
  503. /// </summary>
  504. /// <param name="sender">The sender of the event</param>
  505. /// <param name="e">The event data</param>
  506. /// <remarks>Will close the window without saving</remarks>
  507. private void CloseCancel_Click(object sender, RoutedEventArgs e)
  508. {
  509. Close();
  510. }
  511. /// <summary>
  512. /// Invoked when the user edits the value of a property
  513. /// </summary>
  514. /// <param name="sender">The sender of the event</param>
  515. /// <param name="e">The event data</param>
  516. /// <remarks>Will save the text to the temporary structure</remarks>
  517. private void EditableTextBlock_Edited(object sender, EditableTextBlockEventArgs e)
  518. {
  519. EditableTextBlock etb = sender as EditableTextBlock;
  520. string prop = etb.Tag as string;
  521. PropertyData p = null;
  522. foreach (PropertyData pd in properties)
  523. {
  524. if (pd.Name == prop)
  525. {
  526. p = pd;
  527. break;
  528. }
  529. }
  530. if (p != null)
  531. {
  532. p.Value = e.NewText;
  533. object curObj = GetTag(tempTrack, p.Name);
  534. string cur = curObj as string;
  535. p.Edited = curObj == null || p.Value != curObj.ToString();
  536. }
  537. ToggleButtons();
  538. }
  539. /// <summary>
  540. /// Invoked when the user is typing inside the Filename box.
  541. /// </summary>
  542. /// <param name="sender">The sender of the event</param>
  543. /// <param name="e">The event data</param>
  544. /// <remarks>Will refresh the button set</remarks>
  545. private void Filename_KeyUp(object sender, KeyEventArgs e)
  546. {
  547. ToggleButtons();
  548. }
  549. #endregion
  550. #region Dispatchers
  551. /// <summary>
  552. /// Dispatches the NextClick event
  553. /// </summary>
  554. private void OnNext()
  555. {
  556. if (NextClick != null)
  557. NextClick(this, new EventArgs());
  558. }
  559. /// <summary>
  560. /// Dispatches the PreviousClick event
  561. /// </summary>
  562. private void OnPrev()
  563. {
  564. if (PreviousClick != null)
  565. PreviousClick(this, new EventArgs());
  566. }
  567. #endregion
  568. #endregion
  569. #region Events
  570. /// <summary>
  571. /// Occurs when the user clicks Next
  572. /// </summary>
  573. public event EventHandler NextClick;
  574. /// <summary>
  575. /// Occurs when the user clicks Previous
  576. /// </summary>
  577. public event EventHandler PreviousClick;
  578. #endregion
  579. }
  580. #region Datastructures
  581. /// <summary>
  582. /// Describes a source
  583. /// </summary>
  584. public class PropertyData : DependencyObject
  585. {
  586. #region Properties
  587. /// <summary>
  588. /// Identifies the Name dependency property
  589. /// </summary>
  590. public static readonly DependencyProperty NameProperty =
  591. DependencyProperty.Register("Name", typeof(string),
  592. typeof(PropertyData), new UIPropertyMetadata(null));
  593. /// <summary>
  594. /// Gets or sets the property name
  595. /// </summary>
  596. public string Name
  597. {
  598. get { return (string)GetValue(NameProperty); }
  599. set { SetValue(NameProperty, value); }
  600. }
  601. /// <summary>
  602. /// Identifies the Value dependency property
  603. /// </summary>
  604. public static readonly DependencyProperty ValueProperty =
  605. DependencyProperty.Register("Value", typeof(string),
  606. typeof(PropertyData), new UIPropertyMetadata(null));
  607. /// <summary>
  608. /// Gets or sets the property value
  609. /// </summary>
  610. public string Value
  611. {
  612. get { return (string)GetValue(ValueProperty); }
  613. set { SetValue(ValueProperty, value); }
  614. }
  615. /// <summary>
  616. /// Gets or sets whether the property has been edited
  617. /// </summary>
  618. public bool Edited { get; set; }
  619. #endregion
  620. }
  621. #endregion
  622. #region Converters
  623. /// <summary>
  624. /// A converter between bool and visibility (visible or hidden)
  625. /// </summary>
  626. public class BoolToVisibilityConverter : IValueConverter
  627. {
  628. /// <summary>
  629. /// Converts two bool values (<paramref name="value"/> and <paramref name="parameter"/>)
  630. /// to a visibility value. If the two bool values are equal it will return Visible,
  631. /// if they are not it will return Hidden.
  632. /// </summary>
  633. /// <param name="value">The bool value</param>
  634. /// <param name="targetType">The type of the target (not used)</param>
  635. /// <param name="parameter">The string representation of a bool</param>
  636. /// <param name="culture">The culture (not used)</param>
  637. /// <returns>Visible if value and parameter are equal, otherwise Hidden</returns>
  638. public object Convert(object value, Type targetType,
  639. object parameter, System.Globalization.CultureInfo culture)
  640. {
  641. bool param = bool.Parse(parameter as string);
  642. bool val = (bool)value;
  643. return val == param ?
  644. Visibility.Visible : Visibility.Hidden;
  645. }
  646. /// <summary>
  647. /// This function is not implemented and will throw an exception if used.
  648. /// </summary>
  649. /// <param name="value">(not used)</param>
  650. /// <param name="targetType">(not used)</param>
  651. /// <param name="parameter">(not used)</param>
  652. /// <param name="culture">(not used)</param>
  653. /// <returns>(nothing)</returns>
  654. public object ConvertBack(object value, Type targetType,
  655. object parameter, System.Globalization.CultureInfo culture)
  656. {
  657. throw new NotImplementedException();
  658. }
  659. }
  660. #endregion
  661. }