I am trying to bind to a static property on a static class, this property contains settings that are deserialized from a file.
我试图绑定到静态类上的静态属性,该属性包含从文件反序列化的设置。
It never works with the following XAML :
它从不与以下XAML一起工作:
<Window.Resources>
<ObjectDataProvider x:Key="wrapper" ObjectType="{x:Type Application:Wrapper}"/>
</Window.Resources>
<ScrollViewer x:Name="scrollViewer" ScrollViewer.VerticalScrollBarVisibility="Auto"DataContext="{Binding Source={StaticResource wrapper}, UpdateSourceTrigger=PropertyChanged}">
<ComboBox x:Name="comboboxThemes"
SelectedIndex="0"
SelectionChanged="ComboBoxThemesSelectionChanged"
Grid.Column="1"
Grid.Row="8"
Margin="4,3" ItemsSource="{Binding Settings.Themes, Mode=OneWay}" SelectedValue="{Binding Settings.LastTheme, Mode=TwoWay}" />
It does work by code however :
但是,它是通过代码工作的:
comboboxThemes.ItemsSource = Settings.Themes;
Any idea ?
任何想法?
Thank you :-)
谢谢:-)
4 个解决方案
#1
5
Your code-behind doesn't perform a binding, it directly assigns a source to the ComboBox
...
您的代码隐藏没有执行绑定,它直接将源分配给ComboBox…
If you want to do the same in XAML, you don't need a binding at all, you just need the StaticExtension
markup extension :
如果你想在XAML中做同样的事情,你根本不需要绑定,你只需要StaticExtension标记扩展:
ItemsSource="{x:Static local:Settings.Themes}"
(where local
is the xmlns mapping for the namespace containing the Settings
class)
(本地是包含设置类的名称空间的xmlns映射)
#2
2
XAML:
XAML:
<Window x:Class="StaticTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:StaticTest="clr-namespace:StaticTest"
Height="300" Width="300">
<StackPanel>
<TextBlock Text="{x:Static StaticTest:MyStaticStuff.MyProp}" />
</StackPanel>
</Window>
Code behind:
背后的代码:
namespace StaticTest
{
public static class MyStaticStuff
{
public static string MyProp { get { return "From static"; } }
}
}
#3
1
I have found the answers !
我找到答案了!
It did silently throw an Exception has been thrown by the target of an invocation i didn't know more ...
它确实无声地抛出了一个异常,这个异常是由我不知道更多的调用的目标抛出的……
I was initializing a log that writes to a file; the designer finally showed up the details of the exception, it was looking for creating the file in Visual Studio directory which is in Program Files, hence a security exception was thrown.
我正在初始化写到文件的日志;设计器最终显示了异常的细节,它正在寻找在程序文件中的Visual Studio目录中创建文件,因此抛出了一个安全异常。
Apparently VS copies the file to its folder, for its Designer.
显然VS将文件复制到它的文件夹中,作为它的设计器。
I fixed it like this :
我是这样固定的:
var isInDesignMode = DesignerProperties.GetIsInDesignMode(SettingsWindow);
if (!isInDesignMode)
{
Log = new WrapperLogManager("log_wrapper.txt");
}
Last but not least, using ObjectDataProvider never worked as well, only through x:Static
最后但并非最不重要的一点是,使用ObjectDataProvider从来都不能正常工作,只能通过x:Static
This was driving me totally crazy for a few days as it's not so hard to bind data; I just learned another lesson !
这让我疯狂了好几天,因为绑定数据并不难;我又上了一课!
#4
0
For the ItemsSource you can use a direct x:Static assignment as shown in the other answers but for the SelectedValue you need a Binding, which requires an instance on which to set a property. You should be able to restructure the static class into a Singleton to provide a bindable instance and property which can still be referenced statically from code, something like:
对于ItemsSource,您可以使用一个直接的x:静态赋值,如其他答案所示,但是对于SelectedValue,您需要一个绑定,它需要一个实例来设置属性。您应该能够将静态类重组为一个单例,以提供可绑定的实例和属性,这些实例和属性仍然可以从代码中静态引用,比如:
public class Settings : INotifyPropertyChanged
{
public static Settings Instance { get; private set; }
public static IEnumerable<string> Themes { get; set; }
private string _lastTheme;
public string LastTheme
{
get { return _lastTheme; }
set
{
if (_lastTheme == value)
return;
_lastTheme = value;
PropertyChanged(this, new PropertyChangedEventArgs("LastTheme"));
}
}
static Settings()
{
Themes = new ObservableCollection<string> { "One", "Two", "Three", "Four", "Five" };
Instance = new Settings();
}
public event PropertyChangedEventHandler PropertyChanged;
}
Then the ComboBox would use these bindings:
那么ComboBox将使用这些绑定:
<ComboBox ItemsSource="{x:Static local:Settings.Themes}"
SelectedValue="{Binding Source={x:Static local:Settings.Instance}, Path=LastTheme}" />
#1
5
Your code-behind doesn't perform a binding, it directly assigns a source to the ComboBox
...
您的代码隐藏没有执行绑定,它直接将源分配给ComboBox…
If you want to do the same in XAML, you don't need a binding at all, you just need the StaticExtension
markup extension :
如果你想在XAML中做同样的事情,你根本不需要绑定,你只需要StaticExtension标记扩展:
ItemsSource="{x:Static local:Settings.Themes}"
(where local
is the xmlns mapping for the namespace containing the Settings
class)
(本地是包含设置类的名称空间的xmlns映射)
#2
2
XAML:
XAML:
<Window x:Class="StaticTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:StaticTest="clr-namespace:StaticTest"
Height="300" Width="300">
<StackPanel>
<TextBlock Text="{x:Static StaticTest:MyStaticStuff.MyProp}" />
</StackPanel>
</Window>
Code behind:
背后的代码:
namespace StaticTest
{
public static class MyStaticStuff
{
public static string MyProp { get { return "From static"; } }
}
}
#3
1
I have found the answers !
我找到答案了!
It did silently throw an Exception has been thrown by the target of an invocation i didn't know more ...
它确实无声地抛出了一个异常,这个异常是由我不知道更多的调用的目标抛出的……
I was initializing a log that writes to a file; the designer finally showed up the details of the exception, it was looking for creating the file in Visual Studio directory which is in Program Files, hence a security exception was thrown.
我正在初始化写到文件的日志;设计器最终显示了异常的细节,它正在寻找在程序文件中的Visual Studio目录中创建文件,因此抛出了一个安全异常。
Apparently VS copies the file to its folder, for its Designer.
显然VS将文件复制到它的文件夹中,作为它的设计器。
I fixed it like this :
我是这样固定的:
var isInDesignMode = DesignerProperties.GetIsInDesignMode(SettingsWindow);
if (!isInDesignMode)
{
Log = new WrapperLogManager("log_wrapper.txt");
}
Last but not least, using ObjectDataProvider never worked as well, only through x:Static
最后但并非最不重要的一点是,使用ObjectDataProvider从来都不能正常工作,只能通过x:Static
This was driving me totally crazy for a few days as it's not so hard to bind data; I just learned another lesson !
这让我疯狂了好几天,因为绑定数据并不难;我又上了一课!
#4
0
For the ItemsSource you can use a direct x:Static assignment as shown in the other answers but for the SelectedValue you need a Binding, which requires an instance on which to set a property. You should be able to restructure the static class into a Singleton to provide a bindable instance and property which can still be referenced statically from code, something like:
对于ItemsSource,您可以使用一个直接的x:静态赋值,如其他答案所示,但是对于SelectedValue,您需要一个绑定,它需要一个实例来设置属性。您应该能够将静态类重组为一个单例,以提供可绑定的实例和属性,这些实例和属性仍然可以从代码中静态引用,比如:
public class Settings : INotifyPropertyChanged
{
public static Settings Instance { get; private set; }
public static IEnumerable<string> Themes { get; set; }
private string _lastTheme;
public string LastTheme
{
get { return _lastTheme; }
set
{
if (_lastTheme == value)
return;
_lastTheme = value;
PropertyChanged(this, new PropertyChangedEventArgs("LastTheme"));
}
}
static Settings()
{
Themes = new ObservableCollection<string> { "One", "Two", "Three", "Four", "Five" };
Instance = new Settings();
}
public event PropertyChangedEventHandler PropertyChanged;
}
Then the ComboBox would use these bindings:
那么ComboBox将使用这些绑定:
<ComboBox ItemsSource="{x:Static local:Settings.Themes}"
SelectedValue="{Binding Source={x:Static local:Settings.Instance}, Path=LastTheme}" />