WFP: How do you properly Bind a DependencyProperty to the GUI
- by Robert Ross
I have the following class (abreviated for simplicity). The app it multi-threaded so the Set and Get are a bit more complicated but should be ok.
namespace News.RSS
{
public class FeedEngine : DependencyObject
{
public static readonly DependencyProperty _processing = DependencyProperty.Register("Processing", typeof(bool), typeof(FeedEngine), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender));
public bool Processing
{
get
{
return (bool)this.Dispatcher.Invoke(
DispatcherPriority.Normal, (DispatcherOperationCallback)delegate { return GetValue(_processing); }, Processing);
}
set
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(SendOrPostCallback)delegate { SetValue(_processing, value); },
value);
}
}
public void Poll()
{
while (Running)
{
Processing = true;
//Do my work to read the data feed from remote source
Processing = false;
Thread.Sleep(PollRate);
}
//
}
}
}
Next I have my main form as the following:
<Window x:Class="News.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converter="clr-namespace:News.Converters"
xmlns:local="clr-namespace:News.Lookup"
xmlns:rss="clr-namespace:News.RSS"
Title="News" Height="521" Width="927" Initialized="Window_Initialized" Closing="Window_Closing" >
<Window.Resources>
<ResourceDictionary>
<converter:BooleanConverter x:Key="boolConverter" />
<converter:ArithmeticConverter x:Key="arithConverter" />
...
</ResourceDictionary>
</Window.Resources>
<DockPanel Name="dockPanel1" SnapsToDevicePixels="False" >
<ToolBarPanel Height="37" Name="toolBarPanel" Orientation="Horizontal" DockPanel.Dock="Top" >
<ToolBarPanel.Children>
<Button DataContext="{DynamicResource FeedEngine}" HorizontalAlignment="Right" Name="btnSearch" ToolTip="Search" Click="btnSearch_Click" IsEnabled="{Binding Path=Processing, Converter={StaticResource boolConverter}}">
<Image Width="32" Height="32" Name="imgSearch" Source="{Resx ResxName=News.Properties.Resources, Key=Search}" />
</Button>
...
</DockPanel>
</Window>
As you can see I set the DataContext to FeedEngine and Bind IsEnabled to Processing. I have also tested the boolConverter separately and it functions (just applies ! (Not) to a bool).
Here is my Main window code behind in case it helps to debug.
namespace News
{
/// <summary>
/// Interaction logic for Main.xaml
/// </summary>
public partial class Main : Window
{
public FeedEngine _engine;
List<NewsItemControl> _newsItems = new List<NewsItemControl>();
Thread _pollingThread;
public Main()
{
InitializeComponent();
this.Show();
}
private void Window_Initialized(object sender, EventArgs e)
{
// Load current Feed data.
_engine = new FeedEngine();
ThreadStart start = new ThreadStart(_engine.Poll);
_pollingThread = new Thread(start);
_pollingThread.Start();
}
}
}
Hope someone can see where I missed a step.
Thanks.