我没有使用mvvm-pattern。我直接将我的UI绑定到模型。
我的问题是对模型属性的绑定有效。如果模型属性 MyStringValue 无效且 MyBoolValue - 属性也发生更改,则文本框将显示红色边框。但我的按钮不会更新IsEnabled属性。
我的XAML看起来像那样
<Window x:Class="OkButtonTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:OkButtonTest"
mc:Ignorable="d"
Title="MainWindow">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding MyStringValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
<Button x:Name="MyExampleButton" Grid.Row="1" IsEnabled="{Binding MyBoolValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Click="Button_Click" />
</Grid>
</Window>
DataContext绑定到csharp-code的模型:
using System.Windows;
namespace OkButtonTest
{
public partial class MainWindow : Window
{
ModelExample modelExample = new ModelExample();
public MainWindow()
{
InitializeComponent();
DataContext = modelExample;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button was clicked");
}
}
}
请注意,我已在我的模型中实现了Fody.PropertyChanged,因此我不需要为每个属性实现PropertyChanged。
using System;
using System.ComponentModel;
namespace OkButtonTest
{
public class ModelExample : INotifyPropertyChanged, IDataErrorInfo
{
public event PropertyChangedEventHandler PropertyChanged;
private string myStringValue = "";
public string MyStringValue
{
get
{
return myStringValue;
}
set
{
myStringValue = value;
}
}
private bool myBoolValue;
public bool MyBoolValue
{
get
{
return myBoolValue;
}
set
{
myBoolValue = value;
Console.WriteLine($"MyBoolValue is {MyBoolValue.ToString()}");
}
}
public string Error
{
get
{
if(MyStringValue.Length < 5)
{
MyBoolValue = false;
return "Invalid string value";
}
MyBoolValue = true;
return string.Empty;
}
}
public string this[string columnName]
{
get
{
return Error;
}
}
}
}
为什么我的按钮没有更新?
答案 0 :(得分:1)
似乎你应该使用以下语法来允许fody预处理你的viewmodel getter和setter。
[AddINotifyPropertyChangedInterface]
public class ModelExample : IDataErrorInfo
{
...
}
还要确保在FodyWeavers.xml
中有此功能<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<PropertyChanged/>
</Weavers>
答案 1 :(得分:1)
仅从string
属性返回Error
并在MyBoolValue
的设置者中设置MyStringValue
属性:
public class ModelExample : INotifyPropertyChanged, IDataErrorInfo
{
public event PropertyChangedEventHandler PropertyChanged;
private string myStringValue = "";
public string MyStringValue
{
get
{
return myStringValue;
}
set
{
myStringValue = value;
MyBoolValue = !string.IsNullOrEmpty(myStringValue) && myStringValue.Length > 4;
}
}
private bool myBoolValue;
public bool MyBoolValue
{
get
{
return myBoolValue;
}
set
{
myBoolValue = value;
}
}
public string Error
{
get
{
if (MyStringValue.Length < 5)
{
return "Invalid string value";
}
return string.Empty;
}
}
public string this[string columnName]
{
get
{
return Error;
}
}
}
吸气者不应该设置任何东西。您当前在MyBoolValue
属性的getter中设置Error
的方法会导致在运行时StackoverflowExcpetion
被抛出。