정적 속성에 바인딩
단순한 정적 문자열 속성을 TextBox에 바인딩하는 데 어려움을 겪고 있습니다.
다음은 정적 속성을 가진 클래스입니다.
public class VersionManager
{
private static string filterString;
public static string FilterString
{
get { return filterString; }
set { filterString = value; }
}
}
xaml에서 이 정적 속성을 TextBox에 바인딩하려고 합니다.
<TextBox>
<TextBox.Text>
<Binding Source="{x:Static local:VersionManager.FilterString}"/>
</TextBox.Text>
</TextBox>
모든 것이 컴파일되지만 런타임에는 다음과 같은 예외가 발생합니다.
'Source' 특성의 값을 'System' 유형의 개체로 변환할 수 없습니다.창문들.Markup.StaticExtension'입니다.'System' 개체에서 오류가 발생했습니다.창문들.마크업 파일 'BurnDisk;component/select version 페이지 함수에 Data.Binding'이 있습니다.xaml' Line 57 위치 29.
내가 뭘 잘못했는지 알아요?
바인딩이 양방향이어야 하는 경우 경로를 제공해야 합니다.
클래스가 정적이 아닌 경우 정적 속성에 대해 양방향 바인딩을 수행하는 방법이 있습니다. 리소스에서 클래스의 더미 인스턴스를 선언하고 바인딩의 소스로 사용합니다.
<Window.Resources>
<local:VersionManager x:Key="versionManager"/>
</Window.Resources>
...
<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>
그런 고정 장치에 고정할 수 없습니다.업데이트가 없기 때문에 바인딩 인프라에서 업데이트에 대한 알림을 받을 수 있는 방법이 없습니다.DependencyObject
(또는 구현하는 객체 인스턴스)INotifyPropertyChanged
) 관련.
값이 변경되지 않으면 바인딩을 버리고 사용합니다.x:Static
바로 안쪽에Text
소유물.정의app
아래는 VersionManager 클래스의 네임스페이스(및 어셈블리) 위치입니다.
<TextBox Text="{x:Static app:VersionManager.FilterString}" />
값이 변경되면 값을 포함하고 바인딩할 싱글톤을 만드는 것이 좋습니다.
싱글톤의 예:
public class VersionManager : DependencyObject {
public static readonly DependencyProperty FilterStringProperty =
DependencyProperty.Register( "FilterString", typeof( string ),
typeof( VersionManager ), new UIPropertyMetadata( "no version!" ) );
public string FilterString {
get { return (string) GetValue( FilterStringProperty ); }
set { SetValue( FilterStringProperty, value ); }
}
public static VersionManager Instance { get; private set; }
static VersionManager() {
Instance = new VersionManager();
}
}
<TextBox Text="{Binding Source={x:Static local:VersionManager.Instance},
Path=FilterString}"/>
.NET 4.5에서는 정적 속성에 바인딩할 수 있습니다. 더 읽어보십시오.
정적 속성을 데이터 바인딩의 원본으로 사용할 수 있습니다.데이터 바인딩 엔진은 정적 이벤트가 발생할 경우 속성 값이 변경되는 시점을 인식합니다.예를 들어 SomeClass 클래스가 MyProperty라는 정적 속성을 정의하는 경우 SomeClass는 MyProperty 값이 변경될 때 발생하는 정적 이벤트를 정의할 수 있습니다.정적 이벤트는 다음 서명 중 하나를 사용할 수 있습니다.
public static event EventHandler MyPropertyChanged;
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
첫 번째 경우 클래스는 이벤트 처리기에 EventArgs를 전달하는 PropertyNameChanged라는 정적 이벤트를 표시합니다.두 번째 경우 클래스는 PropertyChangedEventArgs를 이벤트 핸들러에 전달하는 StaticPropertyChanged라는 정적 이벤트를 표시합니다.정적 속성을 구현하는 클래스는 두 가지 방법 중 하나를 사용하여 속성 변경 알림을 발생시키도록 선택할 수 있습니다.
WPF 4.5부터는 정적 속성에 직접 바인딩할 수 있으며 속성이 변경되면 바인딩이 자동으로 업데이트됩니다.바인딩 업데이트를 트리거하려면 변경 이벤트를 수동으로 연결해야 합니다.
public class VersionManager
{
private static String _filterString;
/// <summary>
/// A static property which you'd like to bind to
/// </summary>
public static String FilterString
{
get
{
return _filterString;
}
set
{
_filterString = value;
// Raise a change event
OnFilterStringChanged(EventArgs.Empty);
}
}
// Declare a static event representing changes to your static property
public static event EventHandler FilterStringChanged;
// Raise the change event through this static method
protected static void OnFilterStringChanged(EventArgs e)
{
EventHandler handler = FilterStringChanged;
if (handler != null)
{
handler(null, e);
}
}
static VersionManager()
{
// Set up an empty event handler
FilterStringChanged += (sender, e) => { return; };
}
}
이제 다른 것과 마찬가지로 정적 속성을 바인딩할 수 있습니다.
<TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/>
바인딩에는 두 가지 방법/구문이 있을 수 있습니다.static
소유물.p가 a인 경우static
그러면, 교실에 있는 재산.binding
위해서textbox
다음과 같습니다.
1.
<TextBox Text="{x:Static local:MainWindow.p}" />
2.
<TextBox Text="{Binding Source={x:Static local:MainWindow.p},Mode=OneTime}" />
사용할 수 있습니다.ObjectDataProvider
수업과 그것은MethodName
. 수 있습니다.다음과 같이 표시될 수 있습니다.
<Window.Resources>
<ObjectDataProvider x:Key="versionManager" ObjectType="{x:Type VersionManager}" MethodName="get_FilterString"></ObjectDataProvider>
</Window.Resources>
선언된 개체 데이터 공급자는 다음과 같이 사용할 수 있습니다.
<TextBox Text="{Binding Source={StaticResource versionManager}}" />
로컬 리소스를 사용하는 경우 아래와 같이 참조할 수 있습니다.
<TextBlock Text="{Binding Source={x:Static prop:Resources.PerUnitOfMeasure}}" TextWrapping="Wrap" TextAlignment="Center"/>
.NET 4.5 +용 오른쪽 변형
C#코드
public class VersionManager
{
private static string filterString;
public static string FilterString
{
get => filterString;
set
{
if (filterString == value)
return;
filterString = value;
StaticPropertyChanged?.Invoke(null, FilterStringPropertyEventArgs);
}
}
private static readonly PropertyChangedEventArgs FilterStringPropertyEventArgs = new PropertyChangedEventArgs (nameof(FilterString));
public static event PropertyChangedEventHandler StaticPropertyChanged;
}
XAML 바인딩(괄호에 주의({}가 아닌)
<TextBox Text="{Binding Path=(yournamespace:VersionManager.FilterString)}" />
가장 희박한 답변(.net 4.5 이상):
static public event EventHandler FilterStringChanged;
static string _filterString;
static public string FilterString
{
get { return _filterString; }
set
{
_filterString= value;
FilterStringChanged?.Invoke(null, EventArgs.Empty);
}
}
및 XAML:
<TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/>
브래킷을 소홀히 하지 마십시오.
정적 속성, 원본 속성, 산술 및 기타를 포함하여 Path 속성 값에 복잡한 식을 작성할 수 있도록 제공하는 프로젝트 CalcBinding을 참조하십시오.다음과 같이 작성할 수 있습니다.
<TextBox Text="{c:Binding local:VersionManager.FilterString}"/>
행운을 빕니다.
또 다른 해결책은 다음과 같이 PropertyChanger를 구현하는 일반 클래스를 만드는 것입니다.
public class ViewProps : PropertyChanger
{
private string _MyValue = string.Empty;
public string MyValue
{
get {
return _MyValue
}
set
{
if (_MyValue == value)
{
return;
}
SetProperty(ref _MyValue, value);
}
}
}
그런 다음 사용자가 원하지 않는 위치에 정적 인스턴스를 만듭니다.
public class MyClass
{
private static ViewProps _ViewProps = null;
public static ViewProps ViewProps
{
get
{
if (_ViewProps == null)
{
_ViewProps = new ViewProps();
}
return _ViewProps;
}
}
}
이제 정적 속성으로 사용합니다.
<TextBlock Text="{x:Bind local:MyClass.ViewProps.MyValue, Mode=OneWay}" />
필요한 경우 여기에 PropertyChanger 구현이 있습니다.
public abstract class PropertyChanger : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
다음과 같은 클래스가 있다고 가정합니다.
public static class VersionManager
{
public static string FilterString;
}
다음과 같은 방법으로 정적 변수를 바인딩할 수 있습니다.
<TextBox Text = {x:Static local:VersionManager.FilterString }/>
언급URL : https://stackoverflow.com/questions/936304/binding-to-static-property
'programing' 카테고리의 다른 글
장고 - 해당 테이블 없음: 주.auth_user__old (0) | 2023.05.21 |
---|---|
SQL Server Management Studio 17에서 하나 이상의 구성 요소를 찾을 수 없습니다. (0) | 2023.05.21 |
파일을 만들 디렉터리가 없는 경우 어떻게 디렉터리를 만들 수 있습니까? (0) | 2023.05.21 |
전체 저장 프로시저 코드를 표시하는 방법은 무엇입니까? (0) | 2023.05.21 |
방법은 정적으로 만들 수 있지만, 그래야 합니까? (0) | 2023.05.21 |